Commit 29a4345ca5aadae48493e71576fd06ff51f1dcaa

Authored by 史婷婷
1 parent 7805de30

feat: 搭建+生产线管理、生产线明细-暂存

  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 +}
... ...
  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 +
... ...
  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>
... ...
  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 +}
... ...
  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
... ...
  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
... ...
  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 +}
... ...
  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;
... ...
  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
... ...
  1 +import ReactDOM from 'react-dom/client'
  2 +import './index.less'
  3 +import router from './router'
  4 +
  5 +import {
  6 + RouterProvider,
  7 +} from "react-router-dom";
  8 +
  9 +ReactDOM.createRoot(document.getElementById('root')!).render(
  10 + <RouterProvider router={router} />
  11 +)
... ...
  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
... ...
  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;
... ...
  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
... ...
  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;
... ...
  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
... ...
  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;
... ...
  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
... ...
  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
... ...
  1 +
  2 +// 每个园区都有独立的分支 这里需要更换成对应的corpCode
  3 +export const currentCorpCode = () => {
  4 + return 'qizhi';
  5 +};
  6 +
  7 +export const _baseUrl = "https://test.qgutech.com";
  8 +
  9 +export const baseColorPrimary = '#1677FF';
... ...
  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
... ...
  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
... ...
  1 +/// <reference types="vite/client" />
... ...
  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 +}
... ...
  1 +{
  2 + "files": [],
  3 + "references": [
  4 + { "path": "./tsconfig.app.json" },
  5 + { "path": "./tsconfig.node.json" }
  6 + ]
  7 +}
... ...
  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 +}
... ...
  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 +})
... ...