Showing
31 changed files
with
1171 additions
and
0 deletions
.eslintrc.cjs
0 → 100644
1 | +module.exports = { | |
2 | + root: true, | |
3 | + env: { browser: true, es2020: true }, | |
4 | + extends: [ | |
5 | + 'eslint:recommended', | |
6 | + 'plugin:@typescript-eslint/recommended', | |
7 | + 'plugin:react-hooks/recommended', | |
8 | + ], | |
9 | + ignorePatterns: ['dist', '.eslintrc.cjs'], | |
10 | + parser: '@typescript-eslint/parser', | |
11 | + plugins: ['react-refresh'], | |
12 | + rules: { | |
13 | + 'react-refresh/only-export-components': [ | |
14 | + 'warn', | |
15 | + { allowConstantExport: true }, | |
16 | + ], | |
17 | + }, | |
18 | +} | ... | ... |
README.md
0 → 100644
1 | +# React + TypeScript + Vite | |
2 | + | |
3 | +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. | |
4 | + | |
5 | +Currently, two official plugins are available: | |
6 | + | |
7 | +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh | |
8 | +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh | |
9 | + | |
10 | +## Expanding the ESLint configuration | |
11 | + | |
12 | +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: | |
13 | + | |
14 | +- Configure the top-level `parserOptions` property like this: | |
15 | + | |
16 | +```js | |
17 | +export default tseslint.config({ | |
18 | + languageOptions: { | |
19 | + // other options... | |
20 | + parserOptions: { | |
21 | + project: ['./tsconfig.node.json', './tsconfig.app.json'], | |
22 | + tsconfigRootDir: import.meta.dirname, | |
23 | + }, | |
24 | + }, | |
25 | +}) | |
26 | +``` | |
27 | + | |
28 | +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` | |
29 | +- Optionally add `...tseslint.configs.stylisticTypeChecked` | |
30 | +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: | |
31 | + | ... | ... |
index.html
0 → 100644
1 | +<!doctype html> | |
2 | +<html lang="en"> | |
3 | + <head> | |
4 | + <meta charset="UTF-8" /> | |
5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
6 | + <title></title> | |
7 | + <link rel="icon" href="./seat_logo.png" type="image/x-icon" /> | |
8 | + </head> | |
9 | + <body> | |
10 | + <div id="root"></div> | |
11 | + <script type="module" src="/src/main.tsx"></script> | |
12 | + </body> | |
13 | +</html> | ... | ... |
package.json
0 → 100644
1 | +{ | |
2 | + "name": "sxjx-h5", | |
3 | + "private": true, | |
4 | + "version": "0.0.0", | |
5 | + "type": "module", | |
6 | + "scripts": { | |
7 | + "dev": "vite", | |
8 | + "build": "tsc -b && vite build", | |
9 | + "lint": "eslint .", | |
10 | + "preview": "vite preview" | |
11 | + }, | |
12 | + "dependencies": { | |
13 | + "antd-mobile": "^5.38.1", | |
14 | + "antd-mobile-icons": "^0.3.0", | |
15 | + "axios": "^1.7.9", | |
16 | + "react": "^18.3.1", | |
17 | + "react-dom": "^18.3.1", | |
18 | + "react-router-dom": "^7.1.1" | |
19 | + }, | |
20 | + "devDependencies": { | |
21 | + "@eslint/js": "^9.17.0", | |
22 | + "@types/node": "^22.10.5", | |
23 | + "@types/react": "^18.3.18", | |
24 | + "@types/react-dom": "^18.3.5", | |
25 | + "@vitejs/plugin-react": "^4.3.4", | |
26 | + "eslint": "^9.17.0", | |
27 | + "eslint-plugin-react-hooks": "^5.0.0", | |
28 | + "eslint-plugin-react-refresh": "^0.4.16", | |
29 | + "globals": "^15.14.0", | |
30 | + "less": "^4.2.1", | |
31 | + "less-loader": "^12.2.0", | |
32 | + "postcss-px-to-viewport": "^1.1.1", | |
33 | + "typescript": "~5.6.2", | |
34 | + "typescript-eslint": "^8.18.2", | |
35 | + "vite": "^5.3.4" | |
36 | + } | |
37 | +} | ... | ... |
public/seat_logo.png
0 → 100644
190 Bytes
public/vite.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> | |
\ No newline at end of file | ... | ... |
src/assets/react.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg> | |
\ No newline at end of file | ... | ... |
src/components/nav-bar/back_icon_b.png
0 → 100644
681 Bytes
src/components/nav-bar/back_icon_w.png
0 → 100644
512 Bytes
src/components/nav-bar/index.less
0 → 100644
1 | +.nav-bar-box { | |
2 | + position: fixed; | |
3 | + top: 0; | |
4 | + left: 0; | |
5 | + right: 0; | |
6 | + height: calc( | |
7 | + 88px + constant(safe-area-inset-top) | |
8 | + ); /* 直接扩展高度,因为padding-bottom是内边距 */ | |
9 | + height: calc(88px + env(safe-area-inset-top)); /* 直接扩展高度 */ | |
10 | + padding-top: constant(safe-area-inset-top); /*兼容 iOS<11.2 */ | |
11 | + padding-top: env(safe-area-inset-top); /* 兼容iOS>= 11.2*/ | |
12 | + background: #fff; | |
13 | + z-index: 98; | |
14 | + .adm-nav-bar { | |
15 | + height: 88px; | |
16 | + padding: 0 12px; | |
17 | + .adm-nav-bar-left { | |
18 | + .adm-nav-bar-back { | |
19 | + padding: 0; | |
20 | + .back-icon { | |
21 | + display: block; | |
22 | + width: 48px; | |
23 | + height: 48px; | |
24 | + background: url('./back_icon_b.png') center center no-repeat; | |
25 | + background-size: cover; | |
26 | + &.white { | |
27 | + background: url('./back_icon_w.png') center center no-repeat; | |
28 | + background-size: cover; | |
29 | + } | |
30 | + } | |
31 | + .custom-icon { | |
32 | + width: 16px; | |
33 | + height: 16px; | |
34 | + font-size: 16px; | |
35 | + } | |
36 | + } | |
37 | + } | |
38 | + .adm-nav-bar-title { | |
39 | + font-size: 32px; | |
40 | + color: #242835; | |
41 | + text-align: center; | |
42 | + font-weight: 600; | |
43 | + } | |
44 | + .adm-nav-bar-right { | |
45 | + } | |
46 | + } | |
47 | +} | |
48 | + | |
49 | +.sx-fixed-back { | |
50 | + position: fixed; | |
51 | + right: 15px; | |
52 | + bottom: 210px; | |
53 | + z-index: 999; // 不被其它dom覆盖 | |
54 | + width: 52px; | |
55 | + height: 52px; | |
56 | + display: flex; | |
57 | + align-items: center; | |
58 | + justify-content: center; | |
59 | + border-radius: 50%; | |
60 | + .icon-fixed-back { | |
61 | + width: 22px; | |
62 | + height: 22px; | |
63 | + } | |
64 | +} | |
65 | + | |
66 | +.sx-left-bottom { | |
67 | + position: fixed; | |
68 | + width: 214px; | |
69 | + height: 214px; | |
70 | + left: -107px; | |
71 | + bottom: -107px; | |
72 | + border-radius: 50%; | |
73 | + z-index: 999; | |
74 | + text-align: right; | |
75 | + | |
76 | + &_wrap { | |
77 | + display: inline-block; | |
78 | + margin: 40px 53px 0 0; | |
79 | + text-align: center; | |
80 | + //border: 1px solid red; | |
81 | + | |
82 | + &__icon { | |
83 | + width: 18px; | |
84 | + height: 18px; | |
85 | + color: #fff; | |
86 | + } | |
87 | + | |
88 | + &__text { | |
89 | + color: #fff; | |
90 | + } | |
91 | + } | |
92 | + | |
93 | + &_wrapFocus { | |
94 | + .sx-left-bottom_wrap__icon, | |
95 | + .sx-left-bottom_wrap__text { | |
96 | + color: #3499ff; | |
97 | + } | |
98 | + } | |
99 | +} | |
100 | + | |
101 | +.sx-left-center { | |
102 | + position: fixed; | |
103 | + width: 24px; | |
104 | + height: 52px; | |
105 | + bottom: 120px; | |
106 | + border-radius: 0 52px 52px 0; | |
107 | + background: rgba(52, 153, 255, 0.1); | |
108 | + z-index: 999; | |
109 | + text-align: right; | |
110 | + | |
111 | + &_wrap { | |
112 | + display: inline-block; | |
113 | + color: #3a9cfe; | |
114 | + margin: 15px 10px 0 0; | |
115 | + transform: scale(1.4); | |
116 | + } | |
117 | +} | ... | ... |
src/components/nav-bar/index.tsx
0 → 100644
1 | +import React, { useEffect } from 'react'; | |
2 | +import { NavBar } from 'antd-mobile'; | |
3 | +import './index.less'; | |
4 | +import { useNavigate } from 'react-router-dom'; | |
5 | + | |
6 | +interface NavBarProps { | |
7 | + rightInfo?: any; | |
8 | + showBack?: any; | |
9 | + title?: any; | |
10 | + isWhite?: any; // 是否是白色返回箭头 | |
11 | + style?: any; | |
12 | + backContent?: any; | |
13 | + hiddenHead?: boolean; | |
14 | + customBack?: { | |
15 | + icon: any; | |
16 | + onClick: () => void; | |
17 | + }; | |
18 | +} | |
19 | + | |
20 | +const NavBarSec: React.FC<NavBarProps> = (props) => { | |
21 | + const navigate = useNavigate(); | |
22 | + // @ts-ignore | |
23 | + const title = props?.title || ''; | |
24 | + const backContent = props?.backContent || ''; | |
25 | + const right = props?.rightInfo; | |
26 | + const showBack = props?.showBack; | |
27 | + | |
28 | + const style = props?.style; | |
29 | + | |
30 | + | |
31 | + const back = () => { | |
32 | + navigate(-1); // 回退到上一个页面 | |
33 | + }; | |
34 | + | |
35 | + useEffect(() => { | |
36 | + //放入回调函数中请自行取掉setTimeout | |
37 | + setTimeout(function () { | |
38 | + // 兼容微信浏览器更新title | |
39 | + //利用iframe的onload事件刷新页面 | |
40 | + document.title = title; | |
41 | + const iframe = document.createElement('iframe'); | |
42 | + iframe.style.visibility = 'hidden'; | |
43 | + iframe.style.width = '1px'; | |
44 | + iframe.style.height = '1px'; | |
45 | + iframe.onload = function () { | |
46 | + setTimeout(function () { | |
47 | + document.body.removeChild(iframe); | |
48 | + }, 0); | |
49 | + }; | |
50 | + document.body.appendChild(iframe); | |
51 | + }, 0); | |
52 | + | |
53 | + }, [title]); | |
54 | + | |
55 | + // @ts-ignore | |
56 | + return <div className={'nav-bar-box'}> | |
57 | + <NavBar | |
58 | + backArrow={ | |
59 | + props.customBack?.icon ? ( | |
60 | + <i className={'custom-icon'}>{props.customBack?.icon}</i> | |
61 | + ) : showBack ? ( | |
62 | + <i className={`back-icon ${props?.isWhite ? 'white' : ''}`} /> | |
63 | + ) : '' | |
64 | + } | |
65 | + onBack={props.customBack?.onClick || back} | |
66 | + right={right} | |
67 | + style={style} | |
68 | + back={backContent} | |
69 | + > | |
70 | + {title} | |
71 | + </NavBar> | |
72 | + </div>; | |
73 | +}; | |
74 | + | |
75 | +export default NavBarSec; | ... | ... |
src/index.less
0 → 100644
1 | +:root { | |
2 | + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; | |
3 | + line-height: 1.5; | |
4 | + font-weight: 400; | |
5 | + | |
6 | + color-scheme: light dark; | |
7 | + color: rgba(255, 255, 255, 0.87); | |
8 | + background-color: #242424; | |
9 | + | |
10 | + font-synthesis: none; | |
11 | + text-rendering: optimizeLegibility; | |
12 | + -webkit-font-smoothing: antialiased; | |
13 | + -moz-osx-font-smoothing: grayscale; | |
14 | +} | |
15 | + | |
16 | +a { | |
17 | + font-weight: 500; | |
18 | + color: #646cff; | |
19 | + text-decoration: inherit; | |
20 | +} | |
21 | +a:hover { | |
22 | + color: #535bf2; | |
23 | +} | |
24 | + | |
25 | +body { | |
26 | + margin: 0; | |
27 | + min-height: 100vh; | |
28 | + background: pink; | |
29 | +} | |
30 | + | |
31 | +h1 { | |
32 | + font-size: 3.2em; | |
33 | + line-height: 1.1; | |
34 | +} | |
35 | + | |
36 | +p { | |
37 | + margin: 0; | |
38 | +} | |
39 | + | |
40 | +button { | |
41 | + border-radius: 8px; | |
42 | + border: 1px solid transparent; | |
43 | + padding: 0.6em 1.2em; | |
44 | + font-size: 1em; | |
45 | + font-weight: 500; | |
46 | + font-family: inherit; | |
47 | + background-color: #1a1a1a; | |
48 | + cursor: pointer; | |
49 | + transition: border-color 0.25s; | |
50 | +} | |
51 | +button:hover { | |
52 | + border-color: #646cff; | |
53 | +} | |
54 | +button:focus, | |
55 | +button:focus-visible { | |
56 | + outline: 4px auto -webkit-focus-ring-color; | |
57 | +} | |
58 | + | |
59 | +@media (prefers-color-scheme: light) { | |
60 | + :root { | |
61 | + color: #213547; | |
62 | + background-color: #ffffff; | |
63 | + } | |
64 | + a:hover { | |
65 | + color: #747bff; | |
66 | + } | |
67 | + button { | |
68 | + background-color: #f9f9f9; | |
69 | + } | |
70 | +} | |
71 | + | |
72 | +#root { | |
73 | + background: #fff; | |
74 | +} | |
75 | + | |
76 | +/* Webkit 浏览器(Chrome, Safari, Edge) */ | |
77 | +::-webkit-scrollbar { | |
78 | + width: 5px; /* 或者 height: 12px; 对于水平滚动条 */ | |
79 | +} | |
80 | + | |
81 | +::-webkit-scrollbar-thumb { | |
82 | + background-color: #1D295B; /* 滚动条的颜色 */ | |
83 | + border-radius: 6px; /* 滚动条的圆角 */ | |
84 | +} | |
85 | + | |
86 | + | |
87 | +::-webkit-scrollbar-track { | |
88 | + background-color: #314484; /* 滚动条轨道的颜色 */ | |
89 | + border-radius: 6px; /* 轨道的圆角 */ | |
90 | +} | |
91 | + | |
92 | + | |
93 | +// 一行省略 | |
94 | +.omit1 { | |
95 | + word-break: break-all; | |
96 | + text-overflow: ellipsis; | |
97 | + display: -webkit-box; | |
98 | + -webkit-box-orient: vertical; | |
99 | + -webkit-line-clamp: 1; | |
100 | + overflow: hidden; | |
101 | + overflow-wrap:break-word; | |
102 | + word-break: break-all; | |
103 | +} | |
104 | + | |
105 | +// 两行省略 | |
106 | +.omit2 { | |
107 | + word-break: break-all; | |
108 | + text-overflow: ellipsis; | |
109 | + display: -webkit-box; | |
110 | + -webkit-box-orient: vertical; | |
111 | + -webkit-line-clamp: 2; | |
112 | + overflow: hidden; | |
113 | + overflow-wrap:break-word; | |
114 | + word-break: break-all; | |
115 | +} | |
116 | + | |
117 | +// 三行省略 | |
118 | +.omit3 { | |
119 | + overflow: hidden; | |
120 | + text-overflow: ellipsis; | |
121 | + display: -webkit-box; | |
122 | + -webkit-line-clamp: 3; | |
123 | + -webkit-box-orient: vertical; | |
124 | + overflow-wrap:break-word; | |
125 | + word-break: break-all; | |
126 | +} | |
127 | +//四行省略 | |
128 | +.omit4 { | |
129 | + overflow: hidden; | |
130 | + text-overflow: ellipsis; | |
131 | + display: -webkit-box; | |
132 | + -webkit-line-clamp: 4; | |
133 | + -webkit-box-orient: vertical; | |
134 | + overflow-wrap:break-word; | |
135 | + word-break: break-all; | |
136 | +} | |
137 | + | |
138 | +//四行省略 | |
139 | +.omit5 { | |
140 | + overflow: hidden; | |
141 | + text-overflow: ellipsis; | |
142 | + display: -webkit-box; | |
143 | + -webkit-line-clamp: 5; | |
144 | + -webkit-box-orient: vertical; | |
145 | + overflow-wrap:break-word; | |
146 | + word-break: break-all; | |
147 | +} | |
148 | + | |
149 | +// 六行省略 | |
150 | +.omit6 { | |
151 | + overflow: hidden; | |
152 | + text-overflow: ellipsis; | |
153 | + display: -webkit-box; | |
154 | + -webkit-line-clamp: 6; | |
155 | + -webkit-box-orient: vertical; | |
156 | + overflow-wrap:break-word; | |
157 | + word-break: break-all; | |
158 | +} | |
159 | + | |
160 | +.sxjx-content-main { | |
161 | + background: #f7f7f7; | |
162 | + height: 100vh; | |
163 | + width: 100vw; | |
164 | + box-sizing: border-box; | |
165 | +} | |
166 | + | |
167 | + | |
168 | +// 有头部有底部 | |
169 | +.sxjx-layout-main { | |
170 | + padding-top: calc(88px + constant(safe-area-inset-top)); | |
171 | + padding-top: calc(88px + env(safe-area-inset-top)); | |
172 | + padding-bottom: calc(120px + constant(safe-area-inset-bottom)); | |
173 | + padding-bottom: calc(120px + env(safe-area-inset-bottom)); | |
174 | +} | |
175 | + | |
176 | +// 有头部没有底部 | |
177 | +.sxjx-layout-main-unfoot { | |
178 | + padding-top: calc(88px + constant(safe-area-inset-top)); | |
179 | + padding-top: calc(88px + env(safe-area-inset-top)); | |
180 | +} | |
181 | + | |
182 | +// 没有头部有底部 | |
183 | +.sxjx-layout-main-unhead { | |
184 | + padding-bottom: calc(120px + constant(safe-area-inset-bottom)); | |
185 | + padding-bottom: calc(120px + env(safe-area-inset-bottom)); | |
186 | +} | |
\ No newline at end of file | ... | ... |
src/main.tsx
0 → 100644
src/pages/errorPage.tsx
0 → 100644
1 | +import { useRouteError } from "react-router-dom"; | |
2 | + | |
3 | +export default function ErrorPage() { | |
4 | + const error:any = useRouteError(); | |
5 | + console.error(error); | |
6 | + | |
7 | + return ( | |
8 | + <div id="error-page"> | |
9 | + <h1>Oops!</h1> | |
10 | + <p>Sorry, an unexpected error has occurred.</p> | |
11 | + <p> | |
12 | + <i>{error?.statusText || error?.message}</i> | |
13 | + </p> | |
14 | + </div> | |
15 | + ); | |
16 | +} | |
\ No newline at end of file | ... | ... |
src/pages/production-detail/index.tsx
0 → 100644
1 | +import React from 'react' | |
2 | +import './style.less' | |
3 | +import NavBar from '@/components/nav-bar' | |
4 | +import {baseColorPrimary} from "@/utils/common"; | |
5 | +import {hexToRgba} from "@/utils/utils"; | |
6 | + | |
7 | + | |
8 | +const ProductionManagement: React.FC = () => { | |
9 | + | |
10 | + const list = [ | |
11 | + { | |
12 | + id: '1', | |
13 | + name: '车顶生产线A' | |
14 | + }, | |
15 | + { | |
16 | + id: '2', | |
17 | + name: '车顶生产线B' | |
18 | + }, | |
19 | + { | |
20 | + id: '3', | |
21 | + name: '车顶生产线C' | |
22 | + }, | |
23 | + { | |
24 | + id: '4', | |
25 | + name: '车顶生产线D' | |
26 | + }, | |
27 | + { | |
28 | + id: '5', | |
29 | + name: '车顶生产线E' | |
30 | + }, | |
31 | + { | |
32 | + id: '6', | |
33 | + name: '车顶生产线F' | |
34 | + }, | |
35 | + { | |
36 | + id: '7', | |
37 | + name: '车顶生产线G' | |
38 | + }, | |
39 | + { | |
40 | + id: '8', | |
41 | + name: '车顶生产线H' | |
42 | + }, | |
43 | + { | |
44 | + id: '9', | |
45 | + name: '车顶生产线I' | |
46 | + }, | |
47 | + { | |
48 | + id: '10', | |
49 | + name: '车顶生产线J' | |
50 | + }, | |
51 | + { | |
52 | + id: '11', | |
53 | + name: '车顶生产线K' | |
54 | + }, | |
55 | + { | |
56 | + id: '12', | |
57 | + name: '车顶生车顶生车顶生产线L' | |
58 | + }, | |
59 | + { | |
60 | + id: '13', | |
61 | + name: '车顶生产线M' | |
62 | + }, | |
63 | + { | |
64 | + id: '14', | |
65 | + name: '车顶生产线N' | |
66 | + } | |
67 | + ] | |
68 | + | |
69 | + | |
70 | + return ( | |
71 | + <div className={'sxjx-content-main sxjx-layout-main-unfoot'}> | |
72 | + <div className={'production-management'}> | |
73 | + <NavBar title={'上产线管理'}/> | |
74 | + <div className={'production-management_list'}> | |
75 | + { | |
76 | + list?.map((item: any) => { | |
77 | + return <div | |
78 | + key={item?.id} | |
79 | + className={'production-management_list-item'} | |
80 | + style={{backgroundColor: hexToRgba(baseColorPrimary, 0.6)}} | |
81 | + > | |
82 | + {item?.name} | |
83 | + </div> | |
84 | + }) | |
85 | + } | |
86 | + </div> | |
87 | + </div> | |
88 | + </div> | |
89 | + ) | |
90 | +} | |
91 | + | |
92 | +export default ProductionManagement; | ... | ... |
src/pages/production-detail/style.less
0 → 100644
1 | +.production-management { | |
2 | + background: #f7f7f7; | |
3 | + | |
4 | + &_list { | |
5 | + padding: 60px; | |
6 | + display: flex; | |
7 | + flex-wrap: wrap; | |
8 | + | |
9 | + &-item { | |
10 | + font-size: 28px; | |
11 | + width: 312px; | |
12 | + height: 312px; | |
13 | + color: #fff; | |
14 | + margin-right: 60px; | |
15 | + margin-bottom: 60px; | |
16 | + cursor: pointer; | |
17 | + border-radius: 12px; | |
18 | + display: flex; | |
19 | + align-items: center; | |
20 | + justify-content: center; | |
21 | + line-height: 40px; | |
22 | + padding: 20px; | |
23 | + box-sizing: border-box; | |
24 | + text-align: center; | |
25 | + | |
26 | + &:nth-child(5n) { | |
27 | + margin-right: 0; | |
28 | + } | |
29 | + } | |
30 | + } | |
31 | +} | |
\ No newline at end of file | ... | ... |
src/pages/production-list/index.tsx
0 → 100644
1 | +import React, {useEffect, useState} from 'react' | |
2 | +import './style.less' | |
3 | +import NavBar from '@/components/nav-bar' | |
4 | +import {baseColorPrimary} from "@/utils/common"; | |
5 | +import {hexToRgba} from "@/utils/utils"; | |
6 | +import _mp4 from './mp4.png'; | |
7 | +import _pdf from './pdf.png'; | |
8 | + | |
9 | +import { useSearchParams } from "react-router-dom"; | |
10 | + | |
11 | + | |
12 | +const ProductionList: React.FC = () => { | |
13 | + const [title, setTitle] = useState<string>(''); | |
14 | + // 因是hook,必须写在组件的顶部执行,useSearchParams() 返回的是数组 | |
15 | + const [params] = useSearchParams(); | |
16 | + console.log('ProductionList===params', params) | |
17 | + // 通过 get 方法获取目标参数 | |
18 | + const name = params.get("name") || ""; | |
19 | + | |
20 | + useEffect(() => { | |
21 | + if (name) { | |
22 | + setTitle(name) | |
23 | + } | |
24 | + }, [name]) | |
25 | + | |
26 | + const list = [ | |
27 | + { | |
28 | + id: '1', | |
29 | + name: '工艺流程指导文件', | |
30 | + type: 'pdf' | |
31 | + }, | |
32 | + { | |
33 | + id: '2', | |
34 | + name: '设备操作指导文件', | |
35 | + type: 'mp4' | |
36 | + }, | |
37 | + { | |
38 | + id: '3', | |
39 | + name: '工艺流程指导文件2', | |
40 | + type: 'pdf' | |
41 | + }, | |
42 | + { | |
43 | + id: '4', | |
44 | + name: '工艺流程指导文件3', | |
45 | + type: 'pdf' | |
46 | + }, | |
47 | + { | |
48 | + id: '5', | |
49 | + name: '工艺流程指导文件4', | |
50 | + type: 'pdf' | |
51 | + }, | |
52 | + { | |
53 | + id: '6', | |
54 | + name: '工艺流程指导文件5', | |
55 | + type: 'pdf' | |
56 | + }, | |
57 | + { | |
58 | + id: '7', | |
59 | + name: '设备操作指导文件2', | |
60 | + type: 'mp4' | |
61 | + }, | |
62 | + { | |
63 | + id: '8', | |
64 | + name: '设备设备设备设备设备设备设备操作指导文件3', | |
65 | + type: 'mp4' | |
66 | + }, | |
67 | + { | |
68 | + id: '9', | |
69 | + name: '设备操作指导文件4', | |
70 | + type: 'mp4' | |
71 | + }, | |
72 | + { | |
73 | + id: '10', | |
74 | + name: '设备操作指导文件5', | |
75 | + type: 'mp4' | |
76 | + }, | |
77 | + { | |
78 | + id: '11', | |
79 | + name: '设备操作指导文件6', | |
80 | + type: 'mp4' | |
81 | + }, | |
82 | + { | |
83 | + id: '12', | |
84 | + name: '设备操作指导文件7', | |
85 | + type: 'mp4' | |
86 | + }, | |
87 | + { | |
88 | + id: '13', | |
89 | + name: '设备操作指导文件8', | |
90 | + type: 'mp4' | |
91 | + }, | |
92 | + { | |
93 | + id: '14', | |
94 | + name: '设备操作指导文件9', | |
95 | + type: 'mp4' | |
96 | + }, | |
97 | + { | |
98 | + id: '15', | |
99 | + name: '设备操作指导文件10', | |
100 | + type: 'mp4' | |
101 | + } | |
102 | + ] | |
103 | + | |
104 | + | |
105 | + return ( | |
106 | + <div className={'sxjx-content-main sxjx-layout-main-unfoot'}> | |
107 | + <div className={'production-list'}> | |
108 | + <NavBar title={title} showBack={true}/> | |
109 | + <div className={'production-list_list'}> | |
110 | + { | |
111 | + list?.map((item: any) => { | |
112 | + return <div | |
113 | + key={item?.id} | |
114 | + className={'production-list_list-item'} | |
115 | + style={{backgroundColor: hexToRgba(baseColorPrimary, 0.6)}} | |
116 | + > | |
117 | + <img className={'production-list_list-item-img'} src={item?.type === 'mp4' ? _mp4 : _pdf}/> | |
118 | + <div className={'omit2 production-list_list-item-name'}> | |
119 | + {item?.name} | |
120 | + </div> | |
121 | + </div> | |
122 | + }) | |
123 | + } | |
124 | + </div> | |
125 | + </div> | |
126 | + </div> | |
127 | + ) | |
128 | +} | |
129 | + | |
130 | +export default ProductionList; | ... | ... |
src/pages/production-list/mp4.png
0 → 100644
8.72 KB
src/pages/production-list/pdf.png
0 → 100644
10.4 KB
src/pages/production-list/style.less
0 → 100644
1 | +.production-list { | |
2 | + background: #f7f7f7; | |
3 | + | |
4 | + &_list { | |
5 | + padding: 60px; | |
6 | + display: flex; | |
7 | + flex-wrap: wrap; | |
8 | + | |
9 | + &-item { | |
10 | + width: 312px; | |
11 | + height: 312px; | |
12 | + color: #fff; | |
13 | + margin-right: 60px; | |
14 | + margin-bottom: 60px; | |
15 | + cursor: pointer; | |
16 | + border-radius: 12px; | |
17 | + display: flex; | |
18 | + align-items: center; | |
19 | + justify-content: center; | |
20 | + padding: 20px; | |
21 | + box-sizing: border-box; | |
22 | + text-align: center; | |
23 | + flex-direction: column; | |
24 | + | |
25 | + &:nth-child(5n) { | |
26 | + margin-right: 0; | |
27 | + } | |
28 | + | |
29 | + &-img { | |
30 | + width: 60px; | |
31 | + height: 60px; | |
32 | + margin-bottom: 30px; | |
33 | + } | |
34 | + | |
35 | + &-name { | |
36 | + font-size: 28px; | |
37 | + height: 80px; | |
38 | + line-height: 40px; | |
39 | + } | |
40 | + } | |
41 | + } | |
42 | +} | |
\ No newline at end of file | ... | ... |
src/pages/production-management/index.tsx
0 → 100644
1 | +import React from 'react' | |
2 | +import './style.less' | |
3 | +import NavBar from "@/components/nav-bar" | |
4 | +import {baseColorPrimary} from "@/utils/common"; | |
5 | +import {hexToRgba} from "@/utils/utils"; | |
6 | +import { useNavigate } from "react-router-dom"; | |
7 | + | |
8 | + | |
9 | +const ProductionManagement: React.FC = () => { | |
10 | + const navigate = useNavigate(); | |
11 | + | |
12 | + const list = [ | |
13 | + { | |
14 | + id: '1', | |
15 | + name: '车顶生产线A' | |
16 | + }, | |
17 | + { | |
18 | + id: '2', | |
19 | + name: '车顶生产线B' | |
20 | + }, | |
21 | + { | |
22 | + id: '3', | |
23 | + name: '车顶生产线C' | |
24 | + }, | |
25 | + { | |
26 | + id: '4', | |
27 | + name: '车顶生产线D' | |
28 | + }, | |
29 | + { | |
30 | + id: '5', | |
31 | + name: '车顶生产线E' | |
32 | + }, | |
33 | + { | |
34 | + id: '6', | |
35 | + name: '车顶生产线F' | |
36 | + }, | |
37 | + { | |
38 | + id: '7', | |
39 | + name: '车顶生产线G' | |
40 | + }, | |
41 | + { | |
42 | + id: '8', | |
43 | + name: '车顶生产线H' | |
44 | + }, | |
45 | + { | |
46 | + id: '9', | |
47 | + name: '车顶生产线I' | |
48 | + }, | |
49 | + { | |
50 | + id: '10', | |
51 | + name: '车顶生产线J' | |
52 | + }, | |
53 | + { | |
54 | + id: '11', | |
55 | + name: '车顶生产线K' | |
56 | + }, | |
57 | + { | |
58 | + id: '12', | |
59 | + name: '车顶生车顶生车顶生产线L' | |
60 | + }, | |
61 | + { | |
62 | + id: '13', | |
63 | + name: '车顶生产线M' | |
64 | + }, | |
65 | + { | |
66 | + id: '14', | |
67 | + name: '车顶生产线N' | |
68 | + } | |
69 | + ]; | |
70 | + | |
71 | + const toProductionList = (item: any) => { | |
72 | + console.log('toProductionList-item', item) | |
73 | + navigate(`/production/list?id=${item?.id}&name=${item?.name}`); | |
74 | + } | |
75 | + | |
76 | + | |
77 | + return ( | |
78 | + <div className={'sxjx-content-main sxjx-layout-main-unfoot'}> | |
79 | + <div className={'production-management'}> | |
80 | + <NavBar title={'生产线管理'}/> | |
81 | + <div className={'production-management_list'}> | |
82 | + { | |
83 | + list?.map((item: any) => { | |
84 | + return <div | |
85 | + key={item?.id} | |
86 | + className={'production-management_list-item'} | |
87 | + style={{backgroundColor: hexToRgba(baseColorPrimary, 0.6)}} | |
88 | + onClick={() => toProductionList(item)} | |
89 | + > | |
90 | + {item?.name} | |
91 | + </div> | |
92 | + }) | |
93 | + } | |
94 | + </div> | |
95 | + </div> | |
96 | + </div> | |
97 | + ) | |
98 | +} | |
99 | + | |
100 | +export default ProductionManagement; | ... | ... |
src/pages/production-management/style.less
0 → 100644
1 | +.production-management { | |
2 | + background: #f7f7f7; | |
3 | + | |
4 | + &_list { | |
5 | + padding: 60px; | |
6 | + display: flex; | |
7 | + flex-wrap: wrap; | |
8 | + | |
9 | + &-item { | |
10 | + font-size: 28px; | |
11 | + width: 312px; | |
12 | + height: 312px; | |
13 | + color: #fff; | |
14 | + margin-right: 60px; | |
15 | + margin-bottom: 60px; | |
16 | + cursor: pointer; | |
17 | + border-radius: 12px; | |
18 | + display: flex; | |
19 | + align-items: center; | |
20 | + justify-content: center; | |
21 | + line-height: 40px; | |
22 | + padding: 20px; | |
23 | + box-sizing: border-box; | |
24 | + text-align: center; | |
25 | + | |
26 | + &:nth-child(5n) { | |
27 | + margin-right: 0; | |
28 | + } | |
29 | + } | |
30 | + } | |
31 | +} | |
\ No newline at end of file | ... | ... |
src/router.tsx
0 → 100644
1 | +import {createHashRouter} from 'react-router-dom'; | |
2 | +import ErrorPage from "./pages/errorPage"; | |
3 | +import ProductionManagement from "./pages/production-management"; | |
4 | +import ProductionList from "./pages/production-list"; | |
5 | +import ProductionDetail from "./pages/production-detail"; | |
6 | + | |
7 | + | |
8 | +const routers = [ | |
9 | + { | |
10 | + path: '/', // 生产线管理 | |
11 | + element: <ProductionManagement />, | |
12 | + errorElement: <ErrorPage />, | |
13 | + }, | |
14 | + { | |
15 | + path: '/production/management', // 生产线管理 | |
16 | + element: <ProductionManagement />, | |
17 | + errorElement: <ErrorPage />, | |
18 | + }, | |
19 | + { | |
20 | + path: '/production/list', // 生产线明细 | |
21 | + element: <ProductionList />, | |
22 | + errorElement: <ErrorPage />, | |
23 | + }, | |
24 | + { | |
25 | + path: '/production/detail', // 生产线详情 | |
26 | + element: <ProductionDetail />, | |
27 | + errorElement: <ErrorPage />, | |
28 | + }, | |
29 | +]; | |
30 | + | |
31 | +export default createHashRouter(routers) | |
\ No newline at end of file | ... | ... |
src/utils/common.tsx
0 → 100644
src/utils/request.tsx
0 → 100644
1 | +import axios from 'axios'; | |
2 | +import {currentCorpCode, _baseUrl} from "./common" | |
3 | + | |
4 | +// 创建axios实例 | |
5 | +const service = axios.create({ | |
6 | + baseURL: _baseUrl, // 你可以通过.env文件设置API的基础URL | |
7 | + timeout: 5000 // 请求超时时间 | |
8 | +}); | |
9 | + | |
10 | +// 请求拦截器 | |
11 | +service.interceptors.request.use( | |
12 | + config => { | |
13 | + // 在发送请求之前做些什么,例如设置请求头 | |
14 | + // if (store.getters.token) { | |
15 | + // config.headers['X-Token'] = getToken(); | |
16 | + // } | |
17 | + console.log('config---2', config) | |
18 | + return config; | |
19 | + }, | |
20 | + error => { | |
21 | + // 对请求错误做些什么 | |
22 | + console.error('请求拦截器错误:', error); // for debug | |
23 | + Promise.reject(error); | |
24 | + } | |
25 | +); | |
26 | + | |
27 | +// 响应拦截器 | |
28 | +service.interceptors.response.use( | |
29 | + response => { | |
30 | + /** | |
31 | + * 可以在这里对响应数据做点什么 | |
32 | + */ | |
33 | + const res = response.data; | |
34 | + if (res?.success || res?.code === 200) { | |
35 | + return res.data; | |
36 | + } else { | |
37 | + // 如果后端有统一的错误码处理,可以在这里统一处理 | |
38 | + console.error('接口错误:', res.message); | |
39 | + // 你可以抛出一个错误,或者返回一个错误对象 | |
40 | + // throw new Error(res.message || 'Error'); | |
41 | + return Promise.reject(new Error(res.message || 'Error')); | |
42 | + } | |
43 | + }, | |
44 | + error => { | |
45 | + console.error('响应拦截器错误:', error); | |
46 | + // 对响应错误做点什么 | |
47 | + return Promise.reject(error); | |
48 | + } | |
49 | +); | |
50 | + | |
51 | +// 封装get请求 | |
52 | +export function get(url: string, params = {}, customHeaders?: any, notCorpCode?: boolean) { | |
53 | + | |
54 | + const _params = notCorpCode ? { | |
55 | + ...params, | |
56 | + } : { | |
57 | + corpCode: currentCorpCode(), | |
58 | + ...params, | |
59 | + } | |
60 | + return service.get(url, {params: _params, headers: customHeaders}) | |
61 | + | |
62 | +} | |
63 | + | |
64 | +// 封装post请求 | |
65 | +export function post(url: string, params = {}, data = {}, customHeaders?: any, notCorpCode?: boolean) { | |
66 | + const _params = notCorpCode ? { | |
67 | + ...params, | |
68 | + } : { | |
69 | + corpCode: currentCorpCode(), | |
70 | + ...params, | |
71 | + } | |
72 | + return service.post(url, data, {params: _params, headers: customHeaders}) | |
73 | +} | |
\ No newline at end of file | ... | ... |
src/utils/utils.tsx
0 → 100644
1 | + | |
2 | +// 十六进制颜色 转换成 rgba | |
3 | +export const hexToRgba = (hex: string | null | undefined, alpha: any) => { | |
4 | + let r: string | number = 0, g: string | number = 0, b: string | number = 0; | |
5 | + | |
6 | + // 3 digits | |
7 | + if (hex?.length == 4) { | |
8 | + r = "0x" + hex?.[1] + hex?.[1]; | |
9 | + g = "0x" + hex?.[2] + hex?.[2]; | |
10 | + b = "0x" + hex?.[3] + hex?.[3]; | |
11 | + // 6 digits | |
12 | + } else if (hex?.length == 7) { | |
13 | + r = "0x" + hex?.[1] + hex?.[2]; | |
14 | + g = "0x" + hex?.[3] + hex?.[4]; | |
15 | + b = "0x" + hex?.[5] + hex?.[6]; | |
16 | + } | |
17 | + | |
18 | + return "rgba(" + +r + "," + +g + "," + +b + "," + alpha + ")"; | |
19 | +} | |
20 | + | |
21 | +// // 使用示例 | |
22 | +// const hexColor = "#ff5733"; // 16进制颜色 | |
23 | +// const opacity = 0.5; // 透明度(0.0 到 1.0) | |
24 | +// const rgbaColor = hexToRgba(hexColor, opacity); | |
25 | +// console.log(rgbaColor); // 输出: "rgba(255, 87, 51, 0.5)" | |
26 | + | |
27 | +export function setFavicon (logoPath: string) { | |
28 | + const link = document.createElement('link'); | |
29 | + link.rel = 'icon'; | |
30 | + link.href = logoPath; | |
31 | + document.head.appendChild(link); | |
32 | +} | |
\ No newline at end of file | ... | ... |
src/vite-env.d.ts
0 → 100644
1 | +/// <reference types="vite/client" /> | ... | ... |
tsconfig.app.json
0 → 100644
1 | +{ | |
2 | + "compilerOptions": { | |
3 | + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", | |
4 | + "target": "ES2020", | |
5 | + "useDefineForClassFields": true, | |
6 | + "lib": ["ES2020", "DOM", "DOM.Iterable"], | |
7 | + "module": "ESNext", | |
8 | + "skipLibCheck": true, | |
9 | + | |
10 | + /* Bundler mode */ | |
11 | + "moduleResolution": "bundler", | |
12 | + "allowImportingTsExtensions": true, | |
13 | + "isolatedModules": true, | |
14 | + "moduleDetection": "force", | |
15 | + "noEmit": true, | |
16 | + "jsx": "react-jsx", | |
17 | + | |
18 | + /* Linting */ | |
19 | + "strict": true, | |
20 | + "noUnusedLocals": true, | |
21 | + "noUnusedParameters": true, | |
22 | + "noFallthroughCasesInSwitch": true, | |
23 | + "noUncheckedSideEffectImports": true | |
24 | + }, | |
25 | + "include": ["src"] | |
26 | +} | ... | ... |
tsconfig.json
0 → 100644
tsconfig.node.json
0 → 100644
1 | +{ | |
2 | + "compilerOptions": { | |
3 | + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", | |
4 | + "target": "ES2022", | |
5 | + "lib": ["ES2023"], | |
6 | + "module": "ESNext", | |
7 | + "skipLibCheck": true, | |
8 | + | |
9 | + /* Bundler mode */ | |
10 | + "moduleResolution": "bundler", | |
11 | + "allowImportingTsExtensions": true, | |
12 | + "isolatedModules": true, | |
13 | + "moduleDetection": "force", | |
14 | + "noEmit": true, | |
15 | + | |
16 | + /* Linting */ | |
17 | + "strict": true, | |
18 | + "noUnusedLocals": true, | |
19 | + "noUnusedParameters": true, | |
20 | + "noFallthroughCasesInSwitch": true, | |
21 | + "noUncheckedSideEffectImports": true | |
22 | + }, | |
23 | + "include": ["vite.config.ts"] | |
24 | +} | ... | ... |
vite.config.ts
0 → 100644
1 | +import {defineConfig} from 'vite' | |
2 | +import react from '@vitejs/plugin-react' | |
3 | +import {resolve} from 'path'; | |
4 | +import postCssPxToViewport from 'postcss-px-to-viewport'; | |
5 | + | |
6 | +const _pxToViewPort = { | |
7 | + viewportWidth: 1920, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750 | |
8 | + viewportHeight: 1080, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置 | |
9 | + unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除) | |
10 | + viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw | |
11 | + selectorBlackList: [], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名 | |
12 | + minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值 | |
13 | + mediaQuery: false, // 允许在媒体查询中转换`px` | |
14 | +} | |
15 | + | |
16 | +// https://vitejs.dev/config/ | |
17 | +export default defineConfig({ | |
18 | + base: "./", | |
19 | + plugins: [react()], | |
20 | + resolve: { | |
21 | + alias: { | |
22 | + '@': resolve(__dirname, '/src') | |
23 | + }, | |
24 | + extensions: ['.js', '.jsx', '.ts', '.tsx', '.less'] | |
25 | + }, | |
26 | + css: { | |
27 | + preprocessorOptions: { | |
28 | + less: { | |
29 | + // 这里可以配置less的特定选项 | |
30 | + } | |
31 | + }, | |
32 | + postcss: { | |
33 | + plugins: [postCssPxToViewport(_pxToViewPort)] | |
34 | + } | |
35 | + }, | |
36 | +}) | ... | ... |