Commit 48c1320e by 肖康

commit

parent 59043f9b
Showing with 0 additions and 3125 deletions
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
#/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
{
"files": {
"main.css": "/static/css/main.1539bebd.css",
"main.js": "/static/js/main.0bfb798f.js",
"static/media/contactUsBanner.png": "/static/media/contactUsBanner.3589d483b42e3df320a1.png",
"static/media/aboutUsBanner.png": "/static/media/aboutUsBanner.6aff9a629cca34f2447b.png",
"static/media/p404.png": "/static/media/p404.d99ce38b3c2654c5e3f5.png",
"static/media/iconfont.ttf?t=1719816191916": "/static/media/iconfont.e5c9229afc1da3904712.ttf",
"static/media/iconfont.woff?t=1719816191916": "/static/media/iconfont.e42dedab476e8fa9b144.woff",
"static/media/iconfont.woff2?t=1719816191916": "/static/media/iconfont.f461f4d34035e6bf1175.woff2",
"index.html": "/index.html",
"main.1539bebd.css.map": "/static/css/main.1539bebd.css.map",
"main.0bfb798f.js.map": "/static/js/main.0bfb798f.js.map"
},
"entrypoints": [
"static/css/main.1539bebd.css",
"static/js/main.0bfb798f.js"
]
}
\ No newline at end of file
No preview for this file type
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="keywords" content=""><meta name="description" content=""/><link rel="manifest" href="/manifest.json"/><title>麒麟电子商城</title><script defer="defer" src="/static/js/main.0bfb798f.js"></script><link href="/static/css/main.1539bebd.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
\ No newline at end of file
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
This diff could not be displayed because it is too large.
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @remix-run/router v1.17.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router DOM v6.24.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router v6.24.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**![check](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxMiAxOTBoLTY5LjljLTkuOCAwLTE5LjEgNC41LTI1LjEgMTIuMkw0MDQuNyA3MjQuNSAyMDcgNDc0YTMyIDMyIDAgMDAtMjUuMS0xMi4ySDExMmMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlsMjczLjkgMzQ3YzEyLjggMTYuMiAzNy40IDE2LjIgNTAuMyAwbDQ4OC40LTYxOC45YzQuMS01LjEuNC0xMi44LTYuMy0xMi44eiIgLz48L3N2Zz4=) */
/**![close-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNTEyIDY0YzI0Ny40IDAgNDQ4IDIwMC42IDQ0OCA0NDhTNzU5LjQgOTYwIDUxMiA5NjAgNjQgNzU5LjQgNjQgNTEyIDI2NC42IDY0IDUxMiA2NHptMTI3Ljk4IDI3NC44MmgtLjA0bC0uMDguMDZMNTEyIDQ2Ni43NSAzODQuMTQgMzM4Ljg4Yy0uMDQtLjA1LS4wNi0uMDYtLjA4LS4wNmEuMTIuMTIgMCAwMC0uMDcgMGMtLjAzIDAtLjA1LjAxLS4wOS4wNWwtNDUuMDIgNDUuMDJhLjIuMiAwIDAwLS4wNS4wOS4xMi4xMiAwIDAwMCAuMDd2LjAyYS4yNy4yNyAwIDAwLjA2LjA2TDQ2Ni43NSA1MTIgMzM4Ljg4IDYzOS44NmMtLjA1LjA0LS4wNi4wNi0uMDYuMDhhLjEyLjEyIDAgMDAwIC4wN2MwIC4wMy4wMS4wNS4wNS4wOWw0NS4wMiA0NS4wMmEuMi4yIDAgMDAuMDkuMDUuMTIuMTIgMCAwMC4wNyAwYy4wMiAwIC4wNC0uMDEuMDgtLjA1TDUxMiA1NTcuMjVsMTI3Ljg2IDEyNy44N2MuMDQuMDQuMDYuMDUuMDguMDVhLjEyLjEyIDAgMDAuMDcgMGMuMDMgMCAuMDUtLjAxLjA5LS4wNWw0NS4wMi00NS4wMmEuMi4yIDAgMDAuMDUtLjA5LjEyLjEyIDAgMDAwLS4wN3YtLjAyYS4yNy4yNyAwIDAwLS4wNS0uMDZMNTU3LjI1IDUxMmwxMjcuODctMTI3Ljg2Yy4wNC0uMDQuMDUtLjA2LjA1LS4wOGEuMTIuMTIgMCAwMDAtLjA3YzAtLjAzLS4wMS0uMDUtLjA1LS4wOWwtNDUuMDItNDUuMDJhLjIuMiAwIDAwLS4wOS0uMDUuMTIuMTIgMCAwMC0uMDcgMHoiIC8+PC9zdmc+) */
/**![close](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNzk5Ljg2IDE2Ni4zMWMuMDIgMCAuMDQuMDIuMDguMDZsNTcuNjkgNTcuN2MuMDQuMDMuMDUuMDUuMDYuMDhhLjEyLjEyIDAgMDEwIC4wNmMwIC4wMy0uMDIuMDUtLjA2LjA5TDU2OS45MyA1MTJsMjg3LjcgMjg3LjdjLjA0LjA0LjA1LjA2LjA2LjA5YS4xMi4xMiAwIDAxMCAuMDdjMCAuMDItLjAyLjA0LS4wNi4wOGwtNTcuNyA1Ny42OWMtLjAzLjA0LS4wNS4wNS0uMDcuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMyAwLS4wNS0uMDItLjA5LS4wNkw1MTIgNTY5LjkzbC0yODcuNyAyODcuN2MtLjA0LjA0LS4wNi4wNS0uMDkuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMiAwLS4wNC0uMDItLjA4LS4wNmwtNTcuNjktNTcuN2MtLjA0LS4wMy0uMDUtLjA1LS4wNi0uMDdhLjEyLjEyIDAgMDEwLS4wN2MwLS4wMy4wMi0uMDUuMDYtLjA5TDQ1NC4wNyA1MTJsLTI4Ny43LTI4Ny43Yy0uMDQtLjA0LS4wNS0uMDYtLjA2LS4wOWEuMTIuMTIgMCAwMTAtLjA3YzAtLjAyLjAyLS4wNC4wNi0uMDhsNTcuNy01Ny42OWMuMDMtLjA0LjA1LS4wNS4wNy0uMDZhLjEyLjEyIDAgMDEuMDcgMGMuMDMgMCAuMDUuMDIuMDkuMDZMNTEyIDQ1NC4wN2wyODcuNy0yODcuN2MuMDQtLjA0LjA2LS4wNS4wOS0uMDZhLjEyLjEyIDAgMDEuMDcgMHoiIC8+PC9zdmc+) */
/**![double-left](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI3Mi45IDUxMmwyNjUuNC0zMzkuMWM0LjEtNS4yLjQtMTIuOS02LjMtMTIuOWgtNzcuM2MtNC45IDAtOS42IDIuMy0xMi42IDYuMUwxODYuOCA0OTIuM2EzMS45OSAzMS45OSAwIDAwMCAzOS41bDI1NS4zIDMyNi4xYzMgMy45IDcuNyA2LjEgMTIuNiA2LjFINTMyYzYuNyAwIDEwLjQtNy43IDYuMy0xMi45TDI3Mi45IDUxMnptMzA0IDBsMjY1LjQtMzM5LjFjNC4xLTUuMi40LTEyLjktNi4zLTEyLjloLTc3LjNjLTQuOSAwLTkuNiAyLjMtMTIuNiA2LjFMNDkwLjggNDkyLjNhMzEuOTkgMzEuOTkgMCAwMDAgMzkuNWwyNTUuMyAzMjYuMWMzIDMuOSA3LjcgNi4xIDEyLjYgNi4xSDgzNmM2LjcgMCAxMC40LTcuNyA2LjMtMTIuOUw1NzYuOSA1MTJ6IiAvPjwvc3ZnPg==) */
/**![double-right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUzMy4yIDQ5Mi4zTDI3Ny45IDE2Ni4xYy0zLTMuOS03LjctNi4xLTEyLjYtNi4xSDE4OGMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlMNDQ3LjEgNTEyIDE4MS43IDg1MS4xQTcuOTggNy45OCAwIDAwMTg4IDg2NGg3Ny4zYzQuOSAwIDkuNi0yLjMgMTIuNi02LjFsMjU1LjMtMzI2LjFjOS4xLTExLjcgOS4xLTI3LjkgMC0zOS41em0zMDQgMEw1ODEuOSAxNjYuMWMtMy0zLjktNy43LTYuMS0xMi42LTYuMUg0OTJjLTYuNyAwLTEwLjQgNy43LTYuMyAxMi45TDc1MS4xIDUxMiA0ODUuNyA4NTEuMUE3Ljk4IDcuOTggMCAwMDQ5MiA4NjRoNzcuM2M0LjkgMCA5LjYtMi4zIDEyLjYtNi4xbDI1NS4zLTMyNi4xYzkuMS0xMS43IDkuMS0yNy45IDAtMzkuNXoiIC8+PC9zdmc+) */
/**![down](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4NCAyNTZoLTc1Yy01LjEgMC05LjkgMi41LTEyLjkgNi42TDUxMiA2NTQuMiAyMjcuOSAyNjIuNmMtMy00LjEtNy44LTYuNi0xMi45LTYuNmgtNzVjLTYuNSAwLTEwLjMgNy40LTYuNSAxMi43bDM1Mi42IDQ4Ni4xYzEyLjggMTcuNiAzOSAxNy42IDUxLjcgMGwzNTIuNi00ODYuMWMzLjktNS4zLjEtMTIuNy02LjQtMTIuN3oiIC8+PC9zdmc+) */
/**![left](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcyNCAyMTguM1YxNDFjMC02LjctNy43LTEwLjQtMTIuOS02LjNMMjYwLjMgNDg2LjhhMzEuODYgMzEuODYgMCAwMDAgNTAuM2w0NTAuOCAzNTIuMWM1LjMgNC4xIDEyLjkuNCAxMi45LTYuM3YtNzcuM2MwLTQuOS0yLjMtOS42LTYuMS0xMi42bC0zNjAtMjgxIDM2MC0yODEuMWMzLjgtMyA2LjEtNy43IDYuMS0xMi42eiIgLz48L3N2Zz4=) */
/**![loading](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTk4OCA1NDhjLTE5LjkgMC0zNi0xNi4xLTM2LTM2IDAtNTkuNC0xMS42LTExNy0zNC42LTE3MS4zYTQ0MC40NSA0NDAuNDUgMCAwMC05NC4zLTEzOS45IDQzNy43MSA0MzcuNzEgMCAwMC0xMzkuOS05NC4zQzYyOSA4My42IDU3MS40IDcyIDUxMiA3MmMtMTkuOSAwLTM2LTE2LjEtMzYtMzZzMTYuMS0zNiAzNi0zNmM2OS4xIDAgMTM2LjIgMTMuNSAxOTkuMyA0MC4zQzc3Mi4zIDY2IDgyNyAxMDMgODc0IDE1MGM0NyA0NyA4My45IDEwMS44IDEwOS43IDE2Mi43IDI2LjcgNjMuMSA0MC4yIDEzMC4yIDQwLjIgMTk5LjMuMSAxOS45LTE2IDM2LTM1LjkgMzZ6IiAvPjwvc3ZnPg==) */
/**![right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTc2NS43IDQ4Ni44TDMxNC45IDEzNC43QTcuOTcgNy45NyAwIDAwMzAyIDE0MXY3Ny4zYzAgNC45IDIuMyA5LjYgNi4xIDEyLjZsMzYwIDI4MS4xLTM2MCAyODEuMWMtMy45IDMtNi4xIDcuNy02LjEgMTIuNlY4ODNjMCA2LjcgNy43IDEwLjQgMTIuOSA2LjNsNDUwLjgtMzUyLjFhMzEuOTYgMzEuOTYgMCAwMDAtNTAuNHoiIC8+PC9zdmc+) */
/**![search](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkwOS42IDg1NC41TDY0OS45IDU5NC44QzY5MC4yIDU0Mi43IDcxMiA0NzkgNzEyIDQxMmMwLTgwLjItMzEuMy0xNTUuNC04Ny45LTIxMi4xLTU2LjYtNTYuNy0xMzItODcuOS0yMTIuMS04Ny45cy0xNTUuNSAzMS4zLTIxMi4xIDg3LjlDMTQzLjIgMjU2LjUgMTEyIDMzMS44IDExMiA0MTJjMCA4MC4xIDMxLjMgMTU1LjUgODcuOSAyMTIuMUMyNTYuNSA2ODAuOCAzMzEuOCA3MTIgNDEyIDcxMmM2NyAwIDEzMC42LTIxLjggMTgyLjctNjJsMjU5LjcgMjU5LjZhOC4yIDguMiAwIDAwMTEuNiAwbDQzLjYtNDMuNWE4LjIgOC4yIDAgMDAwLTExLjZ6TTU3MC40IDU3MC40QzUyOCA2MTIuNyA0NzEuOCA2MzYgNDEyIDYzNnMtMTE2LTIzLjMtMTU4LjQtNjUuNkMyMTEuMyA1MjggMTg4IDQ3MS44IDE4OCA0MTJzMjMuMy0xMTYuMSA2NS42LTE1OC40QzI5NiAyMTEuMyAzNTIuMiAxODggNDEyIDE4OHMxMTYuMSAyMy4yIDE1OC40IDY1LjZTNjM2IDM1Mi4yIDYzNiA0MTJzLTIzLjMgMTE2LjEtNjUuNiAxNTguNHoiIC8+PC9zdmc+) */
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
{
"name": "react-ts-demos",
"version": "0.1.0",
"private": true,
"proxy": "http://erpweb.liexindev.net",
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.101",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"antd": "^5.18.3",
"axios": "^1.7.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-router-dom": "^6.24.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
No preview for this file type
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="keywords" content="">
<meta name="description" content="" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>麒麟电子商城</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
\ No newline at end of file
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
import './styles/base.min.css'
import './styles/font/iconfont.css'
import { createHashRouter, Outlet, RouterProvider } from "react-router-dom"
import { useEffect, useState } from 'react';
import { CommonConfigDataContext } from "./contexts/CommonConfigDataContext";
import Home from './pages/Home';
import Search from './pages/Search';
import BrandMap from './pages/BrandMap';
import ClassMap from './pages/ClassMap';
import About from './pages/About';
import Contact from './pages/Contact';
import Notice from './pages/Notice';
import GoodsDetail from "./pages/GoodsDetail";
import Category from "./pages/Category";
import Brand from "./pages/Brand";
import Page404 from "./pages/Page404";
import Header from "./components/Header";
import Footer from "./components/Footer";
const Index = () => {
sessionStorage.removeItem('HOME_PAGE_DATAS')
sessionStorage.removeItem('BRANDMAP_PAGE_DATAS')
sessionStorage.removeItem('CLASSMAP_PAGE_DATAS')
return (
<>
<Header />
<Outlet />
<Footer />
</>
);
}
const router = createHashRouter([
{
path: '',
element: <Index />,
children: [
{
path: '/',
element: <Home />
},
{
path: '/search',
element: <Search />
},
{
path: '/detail/:sku_id',
element: <GoodsDetail />
},
{
path: '/brandMap',
element: <BrandMap />
},
{
path: '/brand/:brand_id',
element: <Brand />
},
{
path: '/classMap',
element: <ClassMap />
},
{
path: '/category/:class_id1/:class_id2?',
element: <Category />
},
{
path: '/about',
element: <About />
},
{
path: '/notice',
element: <Notice />
},
{
path: '/contact',
element: <Contact />
}
,
{
path: '*',
element: <Page404 />
}
]
},
]);
const App = () => {
const [commonConfigData, setCommonConfigData] = useState({
qqurl: '',
});
useEffect(() => {
setCommonConfigData({
qqurl: 'https://url.cn/uia2no5Z?_type=wpa&amp;qidian=true'
})
}, []);
return (
<>
<CommonConfigDataContext.Provider value={commonConfigData}>
<RouterProvider router={router} ></RouterProvider>
</CommonConfigDataContext.Provider>
</>
);
}
export default App;
.breadcrumbs{
height:47px;
line-height: 47px;
font-size: 12px;
color: #000000;
a {
margin: 0 10px;
color: #000000;
&:first-child {
margin-left: 0;
}
&:hover{
color:#FF9A00;
}
}
i{
color: #000000;
font-size: 12px;
}
strong {
margin: 0 10px;
color: #919191;
font-weight: normal !important;
}
}
.breadcrumbs{height:47px;line-height:47px;font-size:12px;color:#000000}.breadcrumbs a{margin:0 10px;color:#000000}.breadcrumbs a:first-child{margin-left:0}.breadcrumbs a:hover{color:#FF9A00}.breadcrumbs i{color:#000000;font-size:12px}.breadcrumbs strong{margin:0 10px;color:#919191;font-weight:normal !important}
\ No newline at end of file
import { ReactNode } from 'react'
import './index.min.css'
import { Link } from "react-router-dom"
const BreadNav = (props:{children:ReactNode}) => {
return (
<>
<div className="breadcrumbs w1226">
<Link to='/'>首页</Link>
<i className="icon iconfont icon-xiangyou1"></i>
{props.children}
</div>
</>
)
}
export default BreadNav
\ No newline at end of file
.mv-footer-box{
height: 160px;
background: #F4F4F4;
.cons{
width:1226px;
height:120px;
margin: 0 auto;
padding-top: 25px;
img{
height:70px;
width:70px;
border-radius: 70px;
}
.navlink{
margin-top: 24px;
a{
padding:0 40px;
border-left:1px solid #d1d1d1;
font-size: 14px;
color:#000;
height:19px;
&:hover{color:#FF9A00;}
&:first-child{
border-left:0px;
}
&:last-child{
padding-right: 0px;
}
}
}
}
.footer-bot{
height: 40px;
background: #FF9A00;
.consp{
width: 1226px;
margin: 0 auto;
height: 40px;
line-height: 40px;
color: #FF9A00;
font-size: 14px;
color:#fff;
a{
color:#fff;
margin-left: 30px;
}
}
}
}
\ No newline at end of file
.mv-footer-box{height:160px;background:#F4F4F4}.mv-footer-box .cons{width:1226px;height:120px;margin:0 auto;padding-top:25px}.mv-footer-box .cons img{height:70px;width:70px;border-radius:70px}.mv-footer-box .cons .navlink{margin-top:24px}.mv-footer-box .cons .navlink a{padding:0 40px;border-left:1px solid #d1d1d1;font-size:14px;color:#000;height:19px}.mv-footer-box .cons .navlink a:hover{color:#FF9A00}.mv-footer-box .cons .navlink a:first-child{border-left:0px}.mv-footer-box .cons .navlink a:last-child{padding-right:0px}.mv-footer-box .footer-bot{height:40px;background:#FF9A00}.mv-footer-box .footer-bot .consp{width:1226px;margin:0 auto;height:40px;line-height:40px;color:#FF9A00;font-size:14px;color:#fff}.mv-footer-box .footer-bot .consp a{color:#fff;margin-left:30px}
\ No newline at end of file
import { Link } from 'react-router-dom'
import './index.min.css'
const Footer = () => {
return (
<>
<div className='mv-footer-box'>
<div className='cons boxsiz row bothSide'>
<img src={require('../../images/qq.png')} alt='' />
<div className='row navlink'>
<Link to='/brandMap'>品牌馆</Link>
<Link to='/about'>关于我们</Link>
<Link to='/contact'>联系我们</Link>
</div>
</div>
<div className='footer-bot'>
<div className='consp row bothSide'>
<span>©2021深圳市猎芯科技有限公司 ALL RIGHTS RESERVED <a rel='noopener noreferrer' target='_blank' href='https://beian.miit.gov.cn/#/Integrated/index'>粤ICP备17064931号</a></span>
<span>增值电信业务经营许可证:粤B2-20160350</span>
</div>
</div>
</div>
</>
)
}
export default Footer
\ No newline at end of file
export type ResponseType = {
success: boolean,
data: Array<{
shopId: string,
shopName: string,
cartList: Array<{
productId: string,
imgUrl: string,
weight: string,
title: string,
price: number,
count: number
}>
}>
}
\ No newline at end of file
.mv-nav-big {
height:38px;
border-bottom: 1px solid #FF9A00;
background: #fff;
.navbox {
margin : 0 auto;
width : 1226px;
.class-boxs {
position: relative;
height : 38px;
.title-lc {
line-height : 38px;
height : 38px;
width : 234px;
height : 38px;
background : #FF9A00;
color : #fff;
font-weight : bold;
font-size : 18px;
cursor : pointer;
box-sizing : border-box;
padding-left: 14px;
display: block;
}
.box-one-left {
width : 234px;
height : 460px;
position : absolute;
left : 0px;
top : 39px;
background: rgba(255, 255, 255, 0.98);
display : none;
box-sizing : border-box;
z-index : 3;
border-left: 1px solid rgba(255, 255, 255, 0);
&.index-pages{
display: block;
}
.classleftcons {
width : 234px;
padding : 20px 0;
box-sizing: border-box;
position : relative;
.one-class-group {
color : #313131;
font-size : 14px;
padding-left : 17px;
padding-right: 17px;
.one-class-link {
display : block;
width : 100%;
cursor : pointer;
padding-bottom: 5px;
.spann {
color : #000;
font-size : 16px;
display : block;
height : 35px;
line-height : 35px;
overflow : hidden;
text-overflow: ellipsis;
white-space : nowrap;
span {
transition : all 0.5s;
display : inline-block;
vertical-align: middle;
width : 0px;
overflow : hidden;
i {
font-size: 11px;
color : #FF9A00;
position : relative;
top : -2px;
}
}
}
}
&:hover {
.spann {
color: #FF9A00;
span {
width: 25px;
}
}
}
.box-two-right {
background : #fff;
box-sizing : border-box;
display : block;
height : 460px;
width : 775px;
position : absolute;
left : 234px;
padding-top: 25px;
box-sizing : border-box;
top : 0px;
display : none;
border-left: 0px;
.classconsjk {
width : 775px;
height : 410px;
box-sizing : border-box;
overflow-y : auto;
padding:0 24px;
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-thumb {
border-radius : 6px;
background : #fff;
-webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.2)
}
&::-webkit-scrollbar-track {
border-radius: 0;
background : #f4f4f4
}
}
.two-class-group {
margin-bottom: 10px;
.two-class-link {
width : 130px;
color : #000;
font-weight : bold;
font-size : 14px;
height : 35px;
line-height : 35px;
flex-shrink : 0;
padding-right: 10px;
box-sizing : border-box;
overflow : hidden;
text-overflow: ellipsis;
white-space : nowrap;
&:hover {
color: #FF9A00;
}
}
.three-class-group {
flex-wrap : wrap;
margin-bottom: 5px;
.three-class-link {
flex-shrink : 0;
// width:120px;
padding-right: 20px;
box-sizing : border-box;
margin-bottom: 5px;
height : 30px;
line-height : 30px;
color : #888888;
font-size : 12px;
&:hover {
color: #FF9A00;
}
overflow : hidden;
text-overflow: ellipsis;
white-space : nowrap;
}
}
}
}
&:hover {
.box-two-right {
display: block;
}
}
}
}
}
&:hover {
.box-one-left {
display: block;
}
}
}
.haed-nav-box {
height : 38px;
line-height: 38px;
ul {
box-sizing : border-box;
padding-left: 34px;
}
li {
margin-right: 75px;
a {
font-size: 18px;
color : #000;
}
&.act,
&:hover {
a {
color: #FF9A00;
}
}
}
}
}
}
\ No newline at end of file
.mv-nav-big{height:38px;border-bottom:1px solid #FF9A00;background:#fff}.mv-nav-big .navbox{margin:0 auto;width:1226px}.mv-nav-big .navbox .class-boxs{position:relative;height:38px}.mv-nav-big .navbox .class-boxs .title-lc{line-height:38px;width:234px;height:38px;background:#FF9A00;color:#fff;font-weight:bold;font-size:18px;cursor:pointer;box-sizing:border-box;padding-left:14px;display:block}.mv-nav-big .navbox .class-boxs .box-one-left{width:234px;height:460px;position:absolute;left:0px;top:39px;background:rgba(255,255,255,0.98);display:none;box-sizing:border-box;z-index:3;border-left:1px solid rgba(255,255,255,0)}.mv-nav-big .navbox .class-boxs .box-one-left.index-pages{display:block}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons{width:234px;padding:20px 0;box-sizing:border-box;position:relative}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group{color:#313131;font-size:14px;padding-left:17px;padding-right:17px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .one-class-link{display:block;width:100%;cursor:pointer;padding-bottom:5px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .one-class-link .spann{color:#000;font-size:16px;display:block;height:35px;line-height:35px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .one-class-link .spann span{transition:all .5s;display:inline-block;vertical-align:middle;width:0px;overflow:hidden}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .one-class-link .spann span i{font-size:11px;color:#FF9A00;position:relative;top:-2px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group:hover .spann{color:#FF9A00}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group:hover .spann span{width:25px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right{background:#fff;display:block;height:460px;width:775px;position:absolute;left:234px;padding-top:25px;box-sizing:border-box;top:0px;display:none;border-left:0px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .classconsjk{width:775px;height:410px;box-sizing:border-box;overflow-y:auto;padding:0 24px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .classconsjk::-webkit-scrollbar{width:8px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .classconsjk::-webkit-scrollbar-thumb{border-radius:6px;background:#fff;-webkit-box-shadow:inset 0 0 8px rgba(0,0,0,0.2)}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .classconsjk::-webkit-scrollbar-track{border-radius:0;background:#f4f4f4}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group{margin-bottom:10px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group .two-class-link{width:130px;color:#000;font-weight:bold;font-size:14px;height:35px;line-height:35px;flex-shrink:0;padding-right:10px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group .two-class-link:hover{color:#FF9A00}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group .three-class-group{flex-wrap:wrap;margin-bottom:5px}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group .three-class-group .three-class-link{flex-shrink:0;padding-right:20px;box-sizing:border-box;margin-bottom:5px;height:30px;line-height:30px;color:#888888;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group .box-two-right .two-class-group .three-class-group .three-class-link:hover{color:#FF9A00}.mv-nav-big .navbox .class-boxs .box-one-left .classleftcons .one-class-group:hover .box-two-right{display:block}.mv-nav-big .navbox .class-boxs:hover .box-one-left{display:block}.mv-nav-big .navbox .haed-nav-box{height:38px;line-height:38px}.mv-nav-big .navbox .haed-nav-box ul{box-sizing:border-box;padding-left:34px}.mv-nav-big .navbox .haed-nav-box li{margin-right:75px}.mv-nav-big .navbox .haed-nav-box li a{font-size:18px;color:#000}.mv-nav-big .navbox .haed-nav-box li.act a,.mv-nav-big .navbox .haed-nav-box li:hover a{color:#FF9A00}
\ No newline at end of file
import { Link, useLocation } from 'react-router-dom'
import './index.min.css'
import type { ResponseTypeCateList,classListType } from './types'
import { useEffect, useState } from 'react'
import useRequest from '../../../../hooks/useRequest'
const NavBig = () => {
const location=useLocation()
const items = [{
url: '/',
name: '首页'
}, {
url: '/brandMap',
name: '品牌馆'
}, {
url: '/about',
name: '关于我们'
}, {
url: '/contact',
name: '联系我们'
}]
const { request:classListRequest } = useRequest<ResponseTypeCateList>({manual:true})
const [classLists,setClassLists]=useState<classListType[]>([])
useEffect(()=>{
classListRequest({url: '/api/home/getCateList'}).then(res=>{
if(res?.code===0){
setClassLists(res.data?.nav_list||[])
}
})
},[classListRequest])
return (
<>
<div className='mv-nav-big'>
<div className='navbox row'>
<div className='class-boxs'>
<Link className='title-lc' to='/classMap'>查看全部</Link>
<div className={location.pathname==='/'?'box-one-left index-pages':'box-one-left'} >
<div className='classleftcons'>
{
classLists.map(item => {
return (
<div className='one-class-group' key={item.goods_type_id}>
<div className='one-class-link'>
<Link className='spann' to={`/category/${item.goods_type_id}`}>
<span><i className='icon iconfont icon-sanjiaoxing'></i></span>
{item.goods_type_name}
</Link>
</div>
<div className='box-two-right '>
<div className='classconsjk'>
<div className='two-class-group '>
<Link to={`/category/${item.goods_type_id}`} key={item.goods_type_id} className='two-class-link'>{item.goods_type_name}</Link>
<div className='three-class-group row'>
{
(item.child||[]).map((itemChild,index)=>{
return (
<Link key={itemChild.goods_type_id+index} className='three-class-link' to={`/category/${item.goods_type_id}/${itemChild.goods_type_id}`}>{itemChild.goods_type_name}</Link>
)
})
}
</div>
</div>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
<div className='haed-nav-box'>
<ul className='row'>
{
items.map((item, index) => {
return (
<li className={location.pathname === item.url ? 'act' : ''} key={item.name + index}>
<Link to={item.url}>{item.name}</Link>
</li>
)
})
}
</ul>
</div>
</div>
</div>
</>
)
}
export default NavBig
\ No newline at end of file
export type ResponseTypeCateList = {
code: number | string,
data: {
nav_list: Array<classListType>
} | null,
msg: string
}
export type classListType = {
goods_type_id: string,
goods_type_name: string,
child?: Array<{
goods_type_id: string,
goods_type_name: string,
}>
}
.mv-search-box{
height: 146px;
background: #FFFFFF;
.cons{
width:1226px;
margin:0 auto;
padding-top: 22px;
img{
width: 117px;
height: 97px;
}
.search-input-box{
width: 794px;
height: 40px;
background: #FFFFFF;
border-radius: 2px;
border: 1px solid #FF9A00;
margin-top: 13px;
.input-goods{
width:588px;
height:38px;
line-height: 38px;
padding: 0 15px;
border-right: 1px solid #FF9A00;
}
.input-nums{
width:133px;
height:38px;
line-height: 38px;
padding: 0 15px;
border-right: 1px solid #FF9A00;
}
.searchbtn{
width:71px;
height:38px;
cursor: pointer;
i{
font-size: 26px;
}
color:#FF9A00;
}
}
}
}
\ No newline at end of file
.mv-search-box{height:146px;background:#FFFFFF}.mv-search-box .cons{width:1226px;margin:0 auto;padding-top:22px}.mv-search-box .cons img{width:117px;height:97px}.mv-search-box .cons .search-input-box{width:794px;height:40px;background:#FFFFFF;border-radius:2px;border:1px solid #FF9A00;margin-top:13px}.mv-search-box .cons .search-input-box .input-goods{width:588px;height:38px;line-height:38px;padding:0 15px;border-right:1px solid #FF9A00}.mv-search-box .cons .search-input-box .input-nums{width:133px;height:38px;line-height:38px;padding:0 15px;border-right:1px solid #FF9A00}.mv-search-box .cons .search-input-box .searchbtn{width:71px;height:38px;cursor:pointer;color:#FF9A00}.mv-search-box .cons .search-input-box .searchbtn i{font-size:26px}
\ No newline at end of file
import { Link, useLocation, useNavigate} from 'react-router-dom'
import './index.min.css'
import { useEffect, useState } from 'react'
import { useToast } from '../../../../hooks/useToast'
const SearchH = () => {
const location = useLocation();
let keywords=''
let nums ='';
if(location.pathname==='/search'){
const params = new URLSearchParams(location.search);
keywords=params.get('keyword')||''
nums = params.get('num')||''
}
const [key,setKey]=useState(keywords)
const [num,setNum]=useState(nums)
useEffect(()=>{
if(location.pathname!=='/search'){
setKey('')
setNum('')
}
},[location.pathname])
const navigate=useNavigate()
const {message}=useToast()
const goSearch=()=>{
if(key.trim().length<2){
message("请输入至少2个字符")
return
}
navigate(`/search?keyword=${key}&num=${num}`)
}
const changeNum=((e:React.ChangeEvent<HTMLInputElement>)=>{
const value = e.target.value;
const numericValue = value.replace(/[^0-9]/g, '');
setNum(numericValue)
})
return (
<>
<div className='mv-search-box'>
<div className='cons row bothSide boxsiz'>
<Link to='/'><img src={require('../../../../images/qq.png')} alt='' /></Link>
<div className='search-input-box boxsiz row'>
<input type='text' className='input-goods boxsiz' value={key} onChange={(e)=>{setKey(e.target.value)}} placeholder='请输入元器件型号、参数查找' />
<input type='text' className='input-nums boxsiz' value={num} placeholder='需求数量' onChange={(e)=>{changeNum(e)}}/>
<div className='searchbtn row rowCenter verCenter' onClick={goSearch}><i className='icon iconfont icon-iconfontsousuo '></i></div>
</div>
</div>
</div>
</>
)
}
export default SearchH
\ No newline at end of file
.mv-top-box{
height: 40px;
background: #F4F4F4;
.con{
width:1226px;
margin:0 auto;
height:40px;
.line {
height: 18px;
background: #d1d1d1;
width: 1px;
margin: 0px 15px;
}
a{
font-size: 12px;
color:#666;
&:hover{
color: #FF9A00;
}
}
.rqq{
margin-left: 25px;
}
}
}
\ No newline at end of file
.mv-top-box{height:40px;background:#F4F4F4}.mv-top-box .con{width:1226px;margin:0 auto;height:40px}.mv-top-box .con .line{height:18px;background:#d1d1d1;width:1px;margin:0px 15px}.mv-top-box .con a{font-size:12px;color:#666}.mv-top-box .con a:hover{color:#FF9A00}.mv-top-box .con .rqq{margin-left:25px}
\ No newline at end of file
import './index.min.css'
import { Link } from 'react-router-dom'
import QqIcon from '../../../QqIcon'
const TopH=()=>{
return (
<>
<div className='mv-top-box'>
<div className='con row bothSide verCenter'>
<div className='f'></div>
<div className='r row verCenter'>
<Link to='/about'>关于我们</Link>
<span className='line'></span>
<Link to='/contact'>联系我们</Link>
<span className='line'></span>
<Link to='/notice'>公告</Link>
<span className='rqq'><QqIcon /></span>
</div>
</div>
</div>
</>
)
}
export default TopH
\ No newline at end of file
import TopH from "./components/TopH"
import SearchH from "./components/SearchH"
import NavBig from "./components/NavBig"
import { useSeoTitle } from "../../hooks/useSeoTitle"
const Header = () => {
const seoTitle=useSeoTitle()
return (
<>
{seoTitle}
<div className="head-box">
<TopH />
<SearchH />
<NavBig />
</div>
</>
)
}
export default Header
\ No newline at end of file
export type ResponseType = {
success: boolean,
data: Array<{
shopId: string,
shopName: string,
cartList: Array<{
productId: string,
imgUrl: string,
weight: string,
title: string,
price: number,
count: number
}>
}>
}
\ No newline at end of file
.lists-no-datax{
background: #fff;
text-align: center;
padding: 40px;
height: auto;
img{
width: 116px;
height: 116px;
display: block;
margin: 0 auto;
}
p{
font-size: 14px;
font-weight: bold;
color: #313131;
margin-top: 32px;
}
}
\ No newline at end of file
.lists-no-datax{background:#fff;text-align:center;padding:40px;height:auto}.lists-no-datax img{width:116px;height:116px;display:block;margin:0 auto}.lists-no-datax p{font-size:14px;font-weight:bold;color:#313131;margin-top:32px}
\ No newline at end of file
import './index.min.css'
const ListNoData=()=>{
return (
<>
<div className='lists-no-datax'>
<img src={require('../../images/nodata.png')} alt="" />
<p>很抱歉!暂无数据</p>
</div>
</>
)
}
export default ListNoData
\ No newline at end of file
.list-group-one-item{
padding:0px 27px;
background: #fff;
.cons{
border-top: 1px solid #e7e7e7;
padding:10px 0px;
.item{
margin-right: 20px;
box-sizing: border-box;
flex-shrink: 0;
&:last-child{margin-right: 0px;}
.goods-img{
width: 92px;
height: 92px;
}
.goods-name{
font-weight: bold;
font-size: 14px;
color: #000000;
line-height: 19px;
height:38px;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
&:hover{
color:#FF9A00;
cursor: pointer;
}
margin-bottom: 10px;
}
p{
font-size: 12px;
color: #000000;
line-height: 23px;
}
.jtgroup{
font-size: 12px;
color: #000000;
line-height: 23px;
span,strong{width:33.33%;}
}
.ljxunj{
cursor: pointer;
width: 80px;
height: 30px;
background: #FF9A00;
color:#fff;
font-size: 14px;
margin-right: 30px;
text-align: center;
line-height: 30px;
}
&.pt48{padding-top: 48px;}
&.w-198{width:198px;}
&.w-345{width:345px;}
&.w-322{width:322px;}
}
}
}
\ No newline at end of file
.list-group-one-item{padding:0px 27px;background:#fff}.list-group-one-item .cons{border-top:1px solid #e7e7e7;padding:10px 0px}.list-group-one-item .cons .item{margin-right:20px;box-sizing:border-box;flex-shrink:0}.list-group-one-item .cons .item:last-child{margin-right:0px}.list-group-one-item .cons .item .goods-img{width:92px;height:92px}.list-group-one-item .cons .item .goods-name{font-weight:bold;font-size:14px;color:#000000;line-height:19px;height:38px;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;margin-bottom:10px}.list-group-one-item .cons .item .goods-name:hover{color:#FF9A00;cursor:pointer}.list-group-one-item .cons .item p{font-size:12px;color:#000000;line-height:23px}.list-group-one-item .cons .item .jtgroup{font-size:12px;color:#000000;line-height:23px}.list-group-one-item .cons .item .jtgroup span,.list-group-one-item .cons .item .jtgroup strong{width:33.33%}.list-group-one-item .cons .item .ljxunj{cursor:pointer;width:80px;height:30px;background:#FF9A00;color:#fff;font-size:14px;margin-right:30px;text-align:center;line-height:30px}.list-group-one-item .cons .item.pt48{padding-top:48px}.list-group-one-item .cons .item.w-198{width:198px}.list-group-one-item .cons .item.w-345{width:345px}.list-group-one-item .cons .item.w-322{width:322px}
\ No newline at end of file
import { Link } from 'react-router-dom'
import QqIcon from '../QqIcon'
import './index.min.css'
import { useContext } from 'react'
import { CommonConfigDataContext } from '../../contexts/CommonConfigDataContext'
import type {dataListItemType} from './types'
const ListOneItem = (props:dataListItemType) => {
const itemInfo={...props!}
const commonConfigData=useContext(CommonConfigDataContext)
return (
<>
<div className='list-group-one-item'>
<div className='cons row'>
<div className='item'>
<Link to={`/detail/${itemInfo.goods_id}`}><img
src={itemInfo.goods_images||'http://static.ichunt.com//dist/res/home/images/goods_default.png'}
className='goods-img' alt=""
onError={(e) => {
e.currentTarget.src = 'http://static.ichunt.com//dist/res/home/images/goods_default.png';
}}
/>
</Link>
</div>
<div className='item w-198'>
<Link className='goods-name' to={`/detail/${itemInfo.goods_id}`}>{itemInfo.goods_name}</Link>
<p>品牌:{itemInfo.brand_name}</p>
<p>参数:{itemInfo.class_name}</p>
</div>
<div className='item w-345 pt48'>
<p>库存:{itemInfo.stock}</p>
<p>起订量:{itemInfo.moq} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 递增:{itemInfo.multiple}</p>
</div>
<div className='item w-322 '>
{
itemInfo.ladder_price.map((item,index)=>{
return (
<div key={index+item.price_cn} className='jtgroup row'><span>{item.purchases}+</span><strong>¥{item.price_cn||'--'}</strong><strong>¥{item.price_us||'--'}</strong></div>
)
})
}
</div>
<div className='item row'>
<a href={commonConfigData.qqurl} rel="noreferrer" className='ljxunj' target='_blank'>立即询价</a>
<QqIcon />
</div>
</div>
</div>
</>
)
}
export default ListOneItem
\ No newline at end of file
export type dataListItemType = {
sku_name: string;
brand_name: string;
brand_id: string|number;
class_id2?:string|number;
class_id1?:string|number;
class_name2?:string;
class_name: string;
cn_delivery_time: string;
hk_delivery_time: string;
goods_id: string;
goods_images: string;
goods_name: string;
moq: number;
multiple: number;
stock: number;
supplier_name: string;
ladder_price: Array<{
price_cn: number;
price_cost_cn: number;
price_us: number;
purchases: number;
price_cost_us: number;
}>
}
.sort-ranksx {
font-size: 14px;
color : #000000;
padding : 20px 0px;
.left {
.item {
height : 18px;
line-height: 18px;
padding : 0 30px;
border-left: 1px solid #d1d1d1;
cursor : pointer;
position : relative;
&:first-child {
padding-left: 0px;
border-left : 0px;
}
i.icon-bottom {
width : 0px;
height : 0px;
border-style: solid;
border-width: 6px;
border-color: #D8D8D8 transparent transparent transparent;
position : absolute;
top : 10px;
right : 14px;
}
i.icon-top {
width : 0px;
height : 0px;
border-style: solid;
border-width: 6px;
border-color: transparent transparent #D8D8D8 transparent;
position : absolute;
top : -4px;
right : 14px;
}
&.act {
color: #FF9A00;
&.top {
i.icon-top {
border-color: transparent transparent #FF9A00 transparent;
}
}
&.bottom {
i.icon-bottom {
border-color: #FF9A00 transparent transparent transparent;
}
}
}
}
}
.right {
.checkbox {
height : 18px;
width : 18px;
border-radius: 2px;
background : #FFF;
border : 1px solid #ededed;
position : relative;
top : 2px;
margin-right : 6px;
text-align : center;
line-height : 18px;
cursor : pointer;
i {
font-size: 21px;
position : relative;
top : 1px;
left : -1px;
color : rgba(0, 0, 0, 0)
}
&.act {
i {
color: #FF9A00;
}
border-color:#FF9A00;
}
}
span {
margin-left: 6px;
cursor : pointer;
&.act {
color : #FF9A00;
cursor: pointer;
}
}
}
}
\ No newline at end of file
.sort-ranksx{font-size:14px;color:#000000;padding:20px 0px}.sort-ranksx .left .item{height:18px;line-height:18px;padding:0 30px;border-left:1px solid #d1d1d1;cursor:pointer;position:relative}.sort-ranksx .left .item:first-child{padding-left:0px;border-left:0px}.sort-ranksx .left .item i.icon-bottom{width:0px;height:0px;border-style:solid;border-width:6px;border-color:#D8D8D8 transparent transparent transparent;position:absolute;top:10px;right:14px}.sort-ranksx .left .item i.icon-top{width:0px;height:0px;border-style:solid;border-width:6px;border-color:transparent transparent #D8D8D8 transparent;position:absolute;top:-4px;right:14px}.sort-ranksx .left .item.act{color:#FF9A00}.sort-ranksx .left .item.act.top i.icon-top{border-color:transparent transparent #FF9A00 transparent}.sort-ranksx .left .item.act.bottom i.icon-bottom{border-color:#FF9A00 transparent transparent transparent}.sort-ranksx .right .checkbox{height:18px;width:18px;border-radius:2px;background:#FFF;border:1px solid #ededed;position:relative;top:2px;margin-right:6px;text-align:center;line-height:18px;cursor:pointer}.sort-ranksx .right .checkbox i{font-size:21px;position:relative;top:1px;left:-1px;color:rgba(0,0,0,0)}.sort-ranksx .right .checkbox.act{border-color:#FF9A00}.sort-ranksx .right .checkbox.act i{color:#FF9A00}.sort-ranksx .right span{margin-left:6px;cursor:pointer}.sort-ranksx .right span.act{color:#FF9A00;cursor:pointer}
\ No newline at end of file
import { Dispatch, SetStateAction } from 'react';
import './index.min.css'
import type { ListSortType } from './types'
interface ListSortProps {
sortObj: ListSortType;
onChangeSort?: (T: ListSortType) => void; //自定义函数
setSortObj?: Dispatch<SetStateAction<ListSortType>>
}
const ListSort = (props: ListSortProps) => {
const { sortType, isStock, stockSort, priceSort } = props.sortObj
const changeSort = (sortType?: number) => {
const obj_ = { ...props.sortObj }
if (sortType) {
obj_.sortType = sortType
}
if (sortType === 2) {
if (obj_.stockSort === 'top') {
obj_.stockSort = 'bottom'
} else {
obj_.stockSort = 'top'
}
}
if (sortType === 3) {
if (obj_.priceSort === 'top') {
obj_.priceSort = 'bottom'
} else {
obj_.priceSort = 'top'
}
}
if (!sortType) {
obj_.isStock = !obj_.isStock
}
props.setSortObj && props.setSortObj(obj_)
props.onChangeSort && props.onChangeSort(obj_)
}
return (
<>
<div className='sort-ranksx row bothSide'>
<div className='left row'>
<div className={sortType === 1 ? 'item act' : 'item'} onClick={() => { changeSort(1) }}>综合排序</div>
<div className={sortType === 2 ? (stockSort === 'top' ? 'item act top' : 'item act bottom') : 'item'} onClick={() => { changeSort(2) }}>库存<i className="icon-top"></i><i className="icon-bottom"></i></div>
<div className={sortType === 3 ? (priceSort === 'top' ? 'item act top' : 'item act bottom') : 'item'} onClick={() => { changeSort(3) }}>价格<i className="icon-top"></i><i className="icon-bottom"></i></div>
</div>
<div className='right row verCenter'>
<div className={isStock ? 'checkbox act' : 'checkbox '} onClick={() => { changeSort() }}>
<i className='icon iconfont icon-B-fuxuankuang'></i>
</div>
<span className={isStock ? 'act' : ''} onClick={() => { changeSort() }}>仅显示有货</span>
</div>
</div>
</>
)
}
export default ListSort
\ No newline at end of file
export type ListSortType = {
sortType:number,//1 综合排序 2库存排序 3价格排序
isStock:boolean,//true 仅有货 false 全部
stockSort?:string, // top 升序 bottom 降序
priceSort?:string // top 升序 bottom 降序
}
import { useContext } from "react";
import { CommonConfigDataContext } from "../../contexts/CommonConfigDataContext";
const QqIcon = () => {
const commonConfigData = useContext(CommonConfigDataContext);
return (
<>
<a href={commonConfigData.qqurl} rel="noreferrer" target='_blank' title='QQ咨询'><img style={{width:'25px',height:'25px'}} src={require('../../images/qq.png')} alt='' /></a>
</>
)
}
export default QqIcon
\ No newline at end of file
import { createContext} from 'react';
export const CommonConfigDataContext = createContext({qqurl:''})
\ No newline at end of file
export const useCookies = () => {
const setCookie = (
name: string,
value: string | number,
time: number,
domain?: string
) => {
let domainStr = domain ? `;domain=${domain}` : '';
const exp = new Date(); // 当前时间
exp.setTime(exp.getTime() + time * 24 * 60 * 60 * 1000); // 设置过期时间
document.cookie = `${name}=${encodeURIComponent(value)};expires=${exp.toUTCString()};path=/${domainStr}`;
return true;
}
const getCookie = (name: string): string | null => {
const cookiesArray = document.cookie.split(';');
for (let i = 0; i < cookiesArray.length; i++) {
let cookiePair = cookiesArray[i].trim();
let cookieRegex = new RegExp(`${name}=`);
if (cookieRegex.test(cookiePair)) {
return decodeURIComponent(cookiePair.replace(cookieRegex, ''));
}
}
return null;
}
return { setCookie, getCookie }
}
import { useCallback, useEffect, useRef, useState } from 'react';
import axios, { AxiosRequestConfig } from "axios"
import { useToast } from './useToast';
// 默认请求参数
const defaultRequestConfig = {
url: '/', method: 'GET', data: {}, params: {}
}
function useRequest<T>(options: AxiosRequestConfig & { manual?: boolean,loading?:boolean|undefined } = defaultRequestConfig) {
const [data, setData] = useState<T | null>(null)
const [loaded, setLoaded] = useState(false)
const {loading,message}=useToast()
const loadingRef = useRef(loading);
const messageRef = useRef(message);
const controllerRef = useRef(new AbortController())
const cancel = () => {
controllerRef.current.abort()
}
const request = useCallback((requestOption?: AxiosRequestConfig) => {
setData(null)
setLoaded(false)
if(options.loading!==false){
loadingRef.current()
}
return axios.request<T>({
baseURL:'http://erpweb.liexindev.net',
...requestOption,
signal: controllerRef.current.signal,
headers: localStorage.getItem("token") ? {
token: localStorage.getItem("token")
} : {}
}).then((response) => {
setData(response.data)
return response.data
}).catch((e: any) => {
messageRef.current(e.message)
}).finally(() => {
loadingRef.current(false)
setLoaded(true)
})
}, [options.loading])
useEffect(() => {
if (!options.manual) {
request(options).catch(e=> {
messageRef.current(e.message)
})
}
}, [options, request])
return { data,loaded, request, cancel }
}
export default useRequest
\ No newline at end of file
import { useLocation } from "react-router-dom"
export const useSeoTitle = () => {
const Helmet = require('react-helmet').Helmet;
const location = useLocation()
let titlestr='404'
const titleKeywords:any = {
'/': { title: '首页', keyword: '' },
'/search': { title: '搜索结果' },
'/detail': { title: '商品详情' },
'/brandMap': { title: '品牌馆' },
'/Brand': { title: '品牌结果' },
'/classMap': { title: '分类地图' },
'/category': { title: '分类结果' },
'/about': { title: '关于我们' },
'/contact': { title: '联系我们' },
'/notice': { title: '公告' },
}
if (Object.keys(titleKeywords).indexOf(location.pathname) !== -1) {
titlestr=titleKeywords[location.pathname]['title']
}
if(location.pathname.indexOf('/detail/')!==-1){
titlestr='商品详情'
}
if(location.pathname.indexOf('/brand/')!==-1){
titlestr='品牌结果'
}
if(location.pathname.indexOf('/category/')!==-1){
titlestr='分类结果'
}
return <Helmet><title>麒麟电子商城-{titlestr}</title></Helmet>
}
import { createRoot } from "react-dom/client";
const tipStyle = {
textAlign: 'center' as const,
fontSize: '14px',
lineHeight: '32px',
fontWeight: 'bold',
position: 'fixed' as const,
top: '170px',
color: '#fff',
zIndex: '99999',
width: '500px',
left: '50%',
marginLeft: '-250px'
}
const tipTextStyle = {
background: 'rgba(0,0,0,0.5)',
paddingLeft: '20px',
paddingRight: '20px',
minWidth: '84px'
}
const loadindStyle={
position: 'fixed' as const,
top:'0px',
left:'0px',
right:'0px',
bottom:'0px',
zIndex: '999999'
}
const loadindImgStyle={
position: 'absolute' as const,
top:'50%',
left:'50%',
marginLeft:'-18px',
marginTop:'-18px',
}
const elementMessage = document.createElement('div');
const rootMessage = createRoot(elementMessage)
const elementLoading = document.createElement('div');
const rootLoading = createRoot(elementLoading)
export const useToast = () => {
const message = (message: string, timeout = 2000) => {
rootMessage.render(
<div style={tipStyle} className="row rowCenter">
<div style={tipTextStyle}>{message}</div>
</div>
);
if (!elementMessage.parentNode) {
document.body.appendChild(elementMessage);
setTimeout(() => {
document.body.removeChild(elementMessage);
}, timeout);
}
}
const loading = ((show=true) => {
rootLoading.render(
<div style={loadindStyle} >
<img src={require('../images/loading.gif')} alt="" style={loadindImgStyle}/>
</div>
);
if(show){
if (!elementLoading.parentNode) {
document.body.appendChild(elementLoading);
}
}else{
if (elementLoading.parentNode) {
document.body.removeChild(elementLoading);
}
}
})
return { message, loading }
}
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<App />
);
.mv-about-page{
.banner{
height:231px;
background: url(../../images/aboutUsBanner.png) no-repeat top center;
}
.section{
background: #fff;
.cons{
padding: 0 143px;
padding-top: 111px;
padding-bottom: 119px;
.left{
width: 267px;
.title{
border-bottom: 1px solid #E7E7E7;
font-weight: bold;
font-size: 20px;
color: #313131;
span{
display: inline-block;
position: relative;
border-bottom: 3px solid #00C69F;
padding-bottom: 22px;
top:2px;
}
}
p{
padding-top: 22px;
font-weight: 400;
font-size: 14px;
color: #000000;
line-height: 30px;
}
}
img{
width: 296px;
height: 245px;
position: relative;
top:58px;
}
}
}
}
\ No newline at end of file
.mv-about-page .banner{height:231px;background:url(../../images/aboutUsBanner.png) no-repeat top center}.mv-about-page .section{background:#fff}.mv-about-page .section .cons{padding:0 143px;padding-top:111px;padding-bottom:119px}.mv-about-page .section .cons .left{width:267px}.mv-about-page .section .cons .left .title{border-bottom:1px solid #E7E7E7;font-weight:bold;font-size:20px;color:#313131}.mv-about-page .section .cons .left .title span{display:inline-block;position:relative;border-bottom:3px solid #00C69F;padding-bottom:22px;top:2px}.mv-about-page .section .cons .left p{padding-top:22px;font-weight:400;font-size:14px;color:#000000;line-height:30px}.mv-about-page .section .cons img{width:296px;height:245px;position:relative;top:58px}
\ No newline at end of file
import './index.min.css'
const About = () => {
return (
<>
<div className='mv-about-page'>
<div className='banner'></div>
<div className='section'>
<div className='cons boxsiz w1226 row bothSide'>
<div className='left'>
<div className='title boxsiz'><span>关于我们</span></div>
<p>
麒麟电子商城(www.chiplinks.net)<br/>
我们是一家小型的电子元器件商城 <br/>
我们是龙年诞生哒!<br/>
我们想为朋友们提供一些帮助,<br/>
虽然可能只是一点点,<br/>
但请给予我们小小的机会,<br/>
请相信我们,<br/>
我们会竭尽全力地成长,<br/>
成为你们希望的模样哦!
</p>
</div>
<img src="https://img.ichunt.com/test/images/cms/202405/30/a263b85bf297ae7d85f68a01b5db320d.jpg" alt="" />
</div>
</div>
</div>
</>
)
}
export default About
\ No newline at end of file
export type ResponseType = {
success: boolean,
data: Array<{
shopId: string,
shopName: string,
cartList: Array<{
productId: string,
imgUrl: string,
weight: string,
title: string,
price: number,
count: number
}>
}>
}
\ No newline at end of file
.mv-brandlist-page{
margin-bottom: 56px;
.brandheadsl{
min-height: 275px;
background: #fff;
padding:26px 60px;
.brandimg{
width: 222px;
height: 222px;
background: #FFFFFF;
border: 1px solid #EDEFEF;
margin-right: 60px;
}
.brand-info{
width:822px;
h2{
font-weight: bold;
font-size: 22px;
color: #000000;
line-height: 29px;
text-align: center;
margin-bottom: 20px;
}
.textBf{
font-size: 14px;
color: #000000;
line-height: 25px;
height: 100px;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
}
.brandbox{
span{
font-size: 12px;
color: #888;
line-height: 20px;
width:80px;
flex-shrink: 0;
}
.itembox{
flex-wrap: wrap;
.item{
height:20px;
line-height: 20px;
font-size: 12px;
color: #000000;
margin-right: 40px;
margin-bottom: 15px;
}
}
}
}
}
.databox{
padding-top: 24px;
.data-group-supplier{
padding-bottom: 20px;
background: #fff;
min-height: 400px;
.sortbixjk{
padding:0 27px;
padding-top: 25px;
}
}
}
}
\ No newline at end of file
.mv-brandlist-page{margin-bottom:56px}.mv-brandlist-page .brandheadsl{min-height:275px;background:#fff;padding:26px 60px}.mv-brandlist-page .brandheadsl .brandimg{width:222px;height:222px;background:#FFFFFF;border:1px solid #EDEFEF;margin-right:60px}.mv-brandlist-page .brandheadsl .brand-info{width:822px}.mv-brandlist-page .brandheadsl .brand-info h2{font-weight:bold;font-size:22px;color:#000000;line-height:29px;text-align:center;margin-bottom:20px}.mv-brandlist-page .brandheadsl .brand-info .textBf{font-size:14px;color:#000000;line-height:25px;height:100px;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4}.mv-brandlist-page .brandheadsl .brand-info .brandbox span{font-size:12px;color:#888;line-height:20px;width:80px;flex-shrink:0}.mv-brandlist-page .brandheadsl .brand-info .brandbox .itembox{flex-wrap:wrap}.mv-brandlist-page .brandheadsl .brand-info .brandbox .itembox .item{height:20px;line-height:20px;font-size:12px;color:#000000;margin-right:40px;margin-bottom:15px}.mv-brandlist-page .databox{padding-top:24px}.mv-brandlist-page .databox .data-group-supplier{padding-bottom:20px;background:#fff;min-height:400px}.mv-brandlist-page .databox .data-group-supplier .sortbixjk{padding:0 27px;padding-top:25px}
\ No newline at end of file
import './index.min.css'
import BreadNav from '../../components/BreadNav';
import ListSort from '../../components/ListSort';
import { useEffect, useRef, useState } from 'react';
import type { ListSortType } from '../../components/ListSort/types'
import type { dataListItemType } from '../../components/ListOneItem/types'
import type { brandResponseType, requestDataType,brandInfoResponseType ,brandInfoType} from './types'
import ListOneItem from '../../components/ListOneItem';
import useRequest from '../../hooks/useRequest';
import { useParams } from 'react-router-dom';
import { Pagination } from 'antd';
import ListNoData from '../../components/ListNoData';
const Brand = () => {
const params = useParams()
const [shouNoData, setShouNoData] = useState(false)
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
const [dataList, setDataList] = useState<dataListItemType[]>([])
const [brandInfo,setBrandInfo]=useState<brandInfoType>()
const [sortObj, setSortObj] = useState<ListSortType>({
sortType: 1,
isStock: false,
stockSort: '',
priceSort: ''
})
const { request: brandListRequest } = useRequest<brandResponseType>({ manual: true })
const { request: brandInfoRequest } = useRequest<brandInfoResponseType>({ manual: true })
const shouldResetPage = useRef(false);
useEffect(() => {
shouldResetPage.current = true;
setPage(1);
}, [sortObj]);
useEffect(() => {
brandInfoRequest({
url: '/api/brand/getBrandDetail',
method: 'get',
params: {brand_id:params.brand_id},
}).then(res => {
if (res?.code === 0) {
setBrandInfo(res?.data)
}
})
}, [params.brand_id,brandInfoRequest]);
useEffect(() => {
if (shouldResetPage.current && page !== 1) {
return
}
shouldResetPage.current = false;
let obj_: requestDataType = { page_size: 10, page: page, standard_brand_id: params.brand_id }
if (sortObj.isStock) {
obj_['stock/gt'] = 0
}
if (sortObj.sortType === 2) {
obj_['stock/sort'] = sortObj.stockSort === 'top' ? 'asc' : 'desc'
}
if (sortObj.sortType === 3) {
obj_['single_price/sort'] = sortObj.priceSort === 'top' ? 'asc' : 'desc'
}
brandListRequest({
url: '/api/search/searchByBrand',
method: 'post',
data: obj_,
}).then(res => {
if (res?.code === 0) {
setTotal(Number(res.data?.total))
setDataList(res.data?.lists || [])
if (res.data?.lists.length > 0) {
setShouNoData(false)
} else {
setShouNoData(true)
}
} else {
setShouNoData(true)
}
})
}, [brandListRequest, params.brand_id, page, sortObj])
const onChange = (page: number) => {
setPage(page)
}
return (
<>
<BreadNav><strong>"{brandInfo?.brand_name}"的型号搜索结果</strong></BreadNav>
<div className='mv-brandlist-page w1226' >
<div className='brandheadsl row boxsiz'>
<img src={brandInfo?.brand_logo||'http://static.ichunt.com//dist/res/home/images/goods_default.png'} alt="" className='brandimg' />
<div className='brand-info'>
<h2>{brandInfo?.brand_name}</h2>
<div className='textBf'>
{brandInfo?.brand_desc}
</div>
{/* <div className='brandbox row '>
<span>分类:</span>
<div className='itembox row'>
<div className='item'>逻辑芯片(200)</div>
<div className='item'>逻辑芯片(200)</div>
</div>
</div> */}
</div>
</div>
<div className='databox'>
<div className='data-group-supplier'>
<div className='sortbixjk'>
<ListSort sortObj={sortObj} setSortObj={setSortObj} />
</div>
{
dataList.map(item => {
return (
<ListOneItem key={item.goods_id} {...item} />
)
})
}
{shouNoData ? <ListNoData /> : ''}
</div>
<Pagination style={{ 'marginTop': '30px' }} current={page} hideOnSinglePage={true} onChange={onChange} total={total} pageSize={10} showSizeChanger={false} />
</div>
</div>
</>
)
}
export default Brand
\ No newline at end of file
import type { dataListItemType } from '../../components/ListOneItem/types'
export type brandResponseType = {
code: number | string,
data: {
lists: Array<dataListItemType>,
total: number|string
},
msg: string
}
export type requestDataType = {
page_size: number,
page: number,
standard_brand_id: string | undefined,
'stock/gt'?: number | string,
'stock/sort'?: 'asc' | 'desc',
'single_price/sort'?: 'asc' | 'desc'
}
export type brandInfoResponseType = {
code: number | string,
data: brandInfoType,
msg: string
}
export type brandInfoType = {
"goods_brand_id": string | number,
"brand_name": string,
"brand_logo": string,
"brand_name_cn": string,
"brand_code": string,
"region": 1,
"brand_desc": string
}
.mv-brand-page{
padding-top: 63px;
margin-bottom: 98px;
.section{
margin-bottom: 70px;
.title{
text-align: center;
font-size: 24px;
color: #000000;
line-height: 31px;
margin-bottom: 45px;
img{
display: block;
margin:0 auto;
margin-top: 2px;
}
}
.itembox{
flex-wrap: wrap;
.item{
width: 233px;
height: 80px;
margin-bottom: 15px;
transition: all 0.5s;
margin-right: 15px;
&:nth-child(5n){
margin-right: 0px;
}
&:hover{
box-shadow: 4px 6px 7px 1px rgba(154,151,149,0.18);
transform: translateY(-1px);
}
img{
width: 233px;
height: 80px;
object-fit: contain;
transform: scale(0.8);
}
}
}
}
}
\ No newline at end of file
.mv-brand-page{padding-top:63px;margin-bottom:98px}.mv-brand-page .section{margin-bottom:70px}.mv-brand-page .section .title{text-align:center;font-size:24px;color:#000000;line-height:31px;margin-bottom:45px}.mv-brand-page .section .title img{display:block;margin:0 auto;margin-top:2px}.mv-brand-page .section .itembox{flex-wrap:wrap}.mv-brand-page .section .itembox .item{width:233px;height:80px;margin-bottom:15px;transition:all .5s;margin-right:15px}.mv-brand-page .section .itembox .item:nth-child(5n){margin-right:0px}.mv-brand-page .section .itembox .item:hover{box-shadow:4px 6px 7px 1px rgba(154,151,149,0.18);transform:translateY(-1px)}.mv-brand-page .section .itembox .item img{width:233px;height:80px;object-fit:contain;transform:scale(.8)}
\ No newline at end of file
import { useEffect, useState } from 'react';
import useRequest from '../../hooks/useRequest';
import './index.min.css'
import { Link } from 'react-router-dom';
import type { brandMapResponseType, brandItenType } from './types';
const BrandMap = () => {
const {request:brandMapRequest} = useRequest<brandMapResponseType>({manual:true})
const [more_brand_list,set_more_brand_list]=useState<Array<brandItenType>>([])
const [popular_brand_list,set_popular_brand_list]=useState<Array<brandItenType>>([])
useEffect(()=>{
if(sessionStorage.getItem('BRANDMAP_PAGE_DATAS')){
set_more_brand_list(JSON.parse(sessionStorage.getItem('BRANDMAP_PAGE_DATAS')!).data.more_brand_list)
set_popular_brand_list(JSON.parse(sessionStorage.getItem('BRANDMAP_PAGE_DATAS')!).data.popular_brand_list)
return
}
brandMapRequest({url:'/api/brand/getBrandList'}).then(res=>{
if(res?.code===0){
set_more_brand_list(res.data.more_brand_list)
set_popular_brand_list(res.data.popular_brand_list)
sessionStorage.setItem('BRANDMAP_PAGE_DATAS',JSON.stringify(res))
}
})
},[brandMapRequest])
return (
<>
<div className='mv-brand-page'>
<div className='section w1226'>
<div className='title'>
热门品牌
<img src={require('../../images/Popular.png')} alt="" />
</div>
<div className='itembox row '>
{
more_brand_list.map((item, index) => {
return (
<Link to={`/brand/${item.goods_brand_id}`} className='item' key={index + String(item.goods_brand_id)}>
<img src={item.brand_logo} alt={item.brand_name} />
</Link>
)
})
}
</div>
</div>
<div className='section w1226'>
<div className='title'>
更多品牌
<img src={require('../../images/More.png')} alt="" />
</div>
<div className='itembox row '>
{
popular_brand_list.map((item, index) => {
return (
<Link to={`/brand/${item.goods_brand_id}`} className='item' key={index + String(item.goods_brand_id)}>
<img src={item.brand_logo} alt={item.brand_name} />
</Link>
)
})
}
</div>
</div>
</div>
</>
)
}
export default BrandMap
\ No newline at end of file
export type brandMapResponseType = {
code: number|string,
data: {
more_brand_list:Array<brandItenType>,
popular_brand_list:Array<brandItenType>
},
msg:string
}
export type brandItenType={
goods_brand_id:number|string,
brand_logo:string,
brand_name:string
}
.mv-category-page{
padding-bottom: 54px;
.categoryHead{
min-height:245px;
background: #fff;
padding:30px 50px;
h2{
font-weight: bold;
font-size: 22px;
color: #000000;
line-height: 29px;
text-align: center;
margin-bottom: 20px;
}
.textBf{
font-size: 14px;
color: #000000;
line-height: 25px;
height: 100px;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
}
.brandbox{
span{
font-weight: bold;
font-size: 14px;
color: #000000;
line-height: 20px;
width:80px;
flex-shrink: 0;
}
.itembox{
flex-wrap: wrap;
.item{
height:20px;
line-height: 20px;
font-size: 14px;
color: #000000;
margin-right: 40px;
margin-bottom: 15px;
}
}
}
}
.databox{
.data-group-supplier{
padding-bottom: 20px;
background: #fff;
min-height: 400px;
.sortbixjk{
padding:0 27px;
padding-top: 25px;
}
}
}
}
\ No newline at end of file
.mv-category-page{padding-bottom:54px}.mv-category-page .categoryHead{min-height:245px;background:#fff;padding:30px 50px}.mv-category-page .categoryHead h2{font-weight:bold;font-size:22px;color:#000000;line-height:29px;text-align:center;margin-bottom:20px}.mv-category-page .categoryHead .textBf{font-size:14px;color:#000000;line-height:25px;height:100px;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4}.mv-category-page .categoryHead .brandbox span{font-weight:bold;font-size:14px;color:#000000;line-height:20px;width:80px;flex-shrink:0}.mv-category-page .categoryHead .brandbox .itembox{flex-wrap:wrap}.mv-category-page .categoryHead .brandbox .itembox .item{height:20px;line-height:20px;font-size:14px;color:#000000;margin-right:40px;margin-bottom:15px}.mv-category-page .databox .data-group-supplier{padding-bottom:20px;background:#fff;min-height:400px}.mv-category-page .databox .data-group-supplier .sortbixjk{padding:0 27px;padding-top:25px}
\ No newline at end of file
import './index.min.css'
import BreadNav from '../../components/BreadNav';
import ListSort from '../../components/ListSort';
import { useEffect, useRef, useState } from 'react';
import type { ListSortType } from '../../components/ListSort/types'
import type { dataListItemType } from '../../components/ListOneItem/types'
import type { classResponseType, requestDataType } from './types'
import ListOneItem from '../../components/ListOneItem';
import useRequest from '../../hooks/useRequest';
import { useParams } from 'react-router-dom';
import { Pagination } from 'antd';
import ListNoData from '../../components/ListNoData';
const Category = () => {
const params = useParams()
const [shouNoData, setShouNoData] = useState(false)
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
const [dataList, setDataList] = useState<dataListItemType[]>([])
const [sortObj, setSortObj] = useState<ListSortType>({
sortType: 1,
isStock: false,
stockSort: '',
priceSort: ''
})
const { request: classInfoRequest } = useRequest<classResponseType>({ manual: true })
const shouldResetPage = useRef(false);
useEffect(() => {
shouldResetPage.current = true;
setPage(1);
}, [sortObj]);
useEffect(() => {
if(shouldResetPage.current&&page!==1){
return
}
shouldResetPage.current = false;
let obj_: requestDataType = { page_size: 10, page: page, class_id1: params.class_id1, class_id2: (params.class_id2 || '') }
if (sortObj.isStock) {
obj_['stock/gt'] = 0
}
if (sortObj.sortType === 2) {
obj_['stock/sort'] = sortObj.stockSort === 'top' ? 'asc' : 'desc'
}
if (sortObj.sortType === 3) {
obj_['single_price/sort'] = sortObj.priceSort === 'top' ? 'asc' : 'desc'
}
classInfoRequest({
url: '/api/search/searchByClass',
method: 'post',
data: obj_,
}).then(res => {
if (res?.code === 0) {
setTotal(Number(res.data?.total))
setDataList(res.data?.lists || [])
if (res.data?.lists.length > 0) {
setShouNoData(false)
} else {
setShouNoData(true)
}
} else {
setShouNoData(true)
}
})
}, [classInfoRequest, params.class_id2, params.class_id1, page,sortObj])
const onChange = (page: number) => {
setPage(page)
}
return (
<>
<BreadNav><strong>分类搜索结果</strong></BreadNav>
<div className='mv-category-page w1226' >
{/* <div className='categoryHead boxsiz'>
<h2>陶瓷电容</h2>
<div className='textBf'>
Lorem ipsum dolor sit amet, ci, sed rhoncus pronin sapien nunc accuan eget.
</div>
<div className='brandbox row '>
<span>品牌:</span>
<div className='itembox row'>
<div className='item'>ON</div>
<div className='item'>NPX</div>
</div>
</div>
</div> */}
<div className='databox w1226'>
<div className='data-group-supplier'>
<div className='sortbixjk'>
<ListSort sortObj={sortObj} setSortObj={setSortObj} />
</div>
{
dataList.map(item => {
return (
<ListOneItem key={item.goods_id} {...item} />
)
})
}
{shouNoData ? <ListNoData /> : ''}
</div>
<Pagination style={{ 'marginTop': '30px' }} current={page} hideOnSinglePage={true} onChange={onChange} total={total} pageSize={10} showSizeChanger={false} />
</div>
</div>
</>
)
}
export default Category
\ No newline at end of file
import type { dataListItemType } from '../../components/ListOneItem/types'
export type classResponseType = {
code: number|string,
data: {
lists:Array<dataListItemType>,
total:number|string
},
msg:string
}
export type requestDataType={
page_size:number,
page:number,
class_id1:string|undefined,
class_id2?:string|undefined,
'stock/gt'?:number|string,
'stock/sort'?:'asc'|'desc',
'single_price/sort'?:'asc'|'desc'
}
.mv-class-page{
margin-bottom: 30px;
min-height: 520px;
h1{
font-weight: bold;
font-size: 20px;
color: #313131;
line-height: 26px;
padding:30px 0px;
}
.itembox{
margin-bottom: 5px;
background: #fff;
padding:32px 28px;
.itemtitle{
font-weight: bold;
font-size: 16px;
color: #000000;
line-height: 35px;
height:35px;
&:hover{
color:#FF9A00;
}
}
.itemcons{
flex-wrap: wrap;
}
.itemlink{
font-size: 14px;
color: #000000;
margin-right: 20px;
margin-top: 15px;
&:hover{
color:#FF9A00;
}
}
}
}
\ No newline at end of file
.mv-class-page{margin-bottom:30px;min-height:520px}.mv-class-page h1{font-weight:bold;font-size:20px;color:#313131;line-height:26px;padding:30px 0px}.mv-class-page .itembox{margin-bottom:5px;background:#fff;padding:32px 28px}.mv-class-page .itembox .itemtitle{font-weight:bold;font-size:16px;color:#000000;line-height:35px;height:35px}.mv-class-page .itembox .itemtitle:hover{color:#FF9A00}.mv-class-page .itembox .itemcons{flex-wrap:wrap}.mv-class-page .itembox .itemlink{font-size:14px;color:#000000;margin-right:20px;margin-top:15px}.mv-class-page .itembox .itemlink:hover{color:#FF9A00}
\ No newline at end of file
import { useEffect, useState } from 'react';
import useRequest from '../../hooks/useRequest';
import './index.min.css'
import { Link } from 'react-router-dom';
import type { classMapResponseType ,classItemType} from './types';
const ClassMap = () => {
const [list,setList]=useState<classItemType[]>([])
const {request:classmapRequest} = useRequest<classMapResponseType>({manual:true})
useEffect(()=>{
if(sessionStorage.getItem('CLASSMAP_PAGE_DATAS')){
setList(JSON.parse(sessionStorage.getItem('CLASSMAP_PAGE_DATAS')!).data)
return
}
classmapRequest({url:'/api/goods/getGoodsType'}).then(res=>{
if(res?.code===0){
setList(res.data)
sessionStorage.setItem('CLASSMAP_PAGE_DATAS',JSON.stringify(res))
}
})
},[classmapRequest])
return (
<>
<div className='mv-class-page'>
<div className='w1226'>
<h1>全部商品</h1>
{
list.map((item, index) => {
return (
<div className='itembox boxsiz' key={String(item.goods_type_id) + index}>
<Link to={`/category/${item.goods_type_id}`} className='itemtitle'>{item.goods_type_name}</Link>
<div className='itemcons flex'>
{
(item.child || []).map((itemChild, indexChild) => {
return (
<Link key={String(itemChild.goods_type_id) + indexChild} to={`/category/${item.goods_type_id}/${itemChild.goods_type_id}`} className='itemlink'>{itemChild.goods_type_name}</Link>
)
})
}
</div>
</div>
)
})
}
</div>
</div>
</>
)
}
export default ClassMap
\ No newline at end of file
export type classMapResponseType = {
code: number | string,
data:classItemType[],
msg: string
}
export type classItemType = {
"goods_type_id": string | number,
"goods_type_name": string,
child?:classItemType[]
}
\ No newline at end of file
.mv-contact-page{
.banner{
height:231px;
background: url(../../images/contactUsBanner.png) no-repeat top center;
}
.section{
background: #fff;
.cons{
padding: 0 143px;
padding-top: 111px;
padding-bottom: 119px;
.left{
width: 267px;
.title{
border-bottom: 1px solid #E7E7E7;
font-weight: bold;
font-size: 20px;
color: #313131;
span{
display: inline-block;
position: relative;
border-bottom: 3px solid #00C69F;
padding-bottom: 22px;
top:2px;
}
}
.lxbox{
padding-top: 30px;
margin-bottom: 25px;
span{
width:44px;
height:44px;
border:1px solid #00C69F;
i{
color:#00C69F;
font-size: 40px;
}
margin-right: 33px;
}
.rxs{
font-size: 16px;
color: #888888;
p{
color:#000000;
font-weight: bold;
margin-top: 7px;
}
}
}
}
img{
width: 296px;
height: 245px;
position: relative;
top:58px;
}
}
}
}
\ No newline at end of file
.mv-contact-page .banner{height:231px;background:url(../../images/contactUsBanner.png) no-repeat top center}.mv-contact-page .section{background:#fff}.mv-contact-page .section .cons{padding:0 143px;padding-top:111px;padding-bottom:119px}.mv-contact-page .section .cons .left{width:267px}.mv-contact-page .section .cons .left .title{border-bottom:1px solid #E7E7E7;font-weight:bold;font-size:20px;color:#313131}.mv-contact-page .section .cons .left .title span{display:inline-block;position:relative;border-bottom:3px solid #00C69F;padding-bottom:22px;top:2px}.mv-contact-page .section .cons .left .lxbox{padding-top:30px;margin-bottom:25px}.mv-contact-page .section .cons .left .lxbox span{width:44px;height:44px;border:1px solid #00C69F;margin-right:33px}.mv-contact-page .section .cons .left .lxbox span i{color:#00C69F;font-size:40px}.mv-contact-page .section .cons .left .lxbox .rxs{font-size:16px;color:#888888}.mv-contact-page .section .cons .left .lxbox .rxs p{color:#000000;font-weight:bold;margin-top:7px}.mv-contact-page .section .cons img{width:296px;height:245px;position:relative;top:58px}
\ No newline at end of file
import './index.min.css'
const Contact = () => {
return (
<>
<div className='mv-contact-page'>
<div className='banner'></div>
<div className='section'>
<div className='cons boxsiz w1226 row bothSide'>
<div className='left'>
<div className='title boxsiz'><span>联系我们</span></div>
<div className='lxbox flex'>
<span className='row verCenter rowCenter'><i className='icon iconfont icon-phone '></i></span>
<div className='rxs'>
热线<p>010-53680391</p>
</div>
</div>
<div className='lxbox flex'>
<span className='row verCenter rowCenter'><i className='icon iconfont icon-email '></i></span>
<div className='rxs'>
邮箱<p>sales@chiplinks.net</p>
</div>
</div>
</div>
<img src="https://img.ichunt.com/test/images/cms/202405/30/a263b85bf297ae7d85f68a01b5db320d.jpg" alt="" />
</div>
</div>
</div>
</>
)
}
export default Contact
\ No newline at end of file
export type ResponseType = {
success: boolean,
data: Array<{
shopId: string,
shopName: string,
cartList: Array<{
productId: string,
imgUrl: string,
weight: string,
title: string,
price: number,
count: number
}>
}>
}
\ No newline at end of file
import QqIcon from "../../../components/QqIcon"
import type { DetailResponseType } from '../types'
import { CommonConfigDataContext } from "../../../contexts/CommonConfigDataContext";
import { useContext } from "react";
const DetailHead = (props: DetailResponseType) => {
const commonConfigData = useContext(CommonConfigDataContext);
const sku_info = props!.data?.sku_info!
return (
<>
<div className='detail-headers w1226 row bothSide boxsiz'>
<div className='l row'>
<img src={sku_info.goods_images || 'http://static.ichunt.com//dist/res/home/images/goods_default.png'} className='goodsimg' alt="" />
<div className='info'>
<div className='box'>
<h1>{sku_info.sku_name}</h1>
<p> 品牌: {sku_info.brand_name}</p>
<p>商品类别:低压差线性稳压(LDO)</p>
<p>封装规格:{sku_info.encap}</p>
<p>描述:{sku_info.remark}</p>
</div>
<div className='handle row bothSide verCenter'>
<QqIcon />
<a href={commonConfigData.qqurl} rel="noreferrer" className='btn' target='_blank'>立即询价</a>
</div>
</div>
</div>
<div className='r boxsiz'>
<p className='row'>
<span className='items'>库存:{sku_info.stock} </span>
<span className='items'>交期:HK {sku_info.hk_delivery_time}</span>
</p>
<p className='row'>
<span className='items'> 批次:{sku_info.batch_sn}</span>
<span className='items'>交期:大陆 {sku_info.cn_delivery_time}</span>
</p>
<p className='row mb23'>
<span className='items'> 起订量: {sku_info.moq}</span>
<span className='items'>递增: {sku_info.multiple}</span>
</p>
{
sku_info.ladder_price.map((item,index) => {
return (
<p className='row' key={index}>
<span className='items'> {item.purchase}+</span>
<span className='items row'><span>¥ {item.price_cn||0}</span><span>$ {item.price_us||0}</span></span>
</p>
)
})
}
</div>
</div>
</>
)
}
export default DetailHead
\ No newline at end of file
import { Link } from "react-router-dom"
import type { DetailResponseType } from '../types'
const DetailSection = (props: DetailResponseType) => {
const attrs = props.data?.sku_info!.attrs || []
const other_sku_list = props!.data?.other_sku_list || []
const goods_details=props.data?.sku_info!.goods_details
return (
<>
<div className='detail-section w1226 row bothSide'>
<div className='secl boxsiz'>
<div className='lilist-box row'>
{
attrs.map((item, index) => {
return (
<p key={item.name + index}>
<b>{item.name}</b>
<span className='ple0'>
<span>{item.value}</span>
</span>
</p>
)
})
}
{attrs.length % 2 === 1 &&
<p >
<b></b>
<span className='ple0'>
<span></span>
</span>
</p>
}
</div>
<div className='row goods-mask goods-mask-two'>
<div>介绍:</div>
<h4 >{goods_details}</h4>
</div>
</div>
<div className="secr">
{
other_sku_list.map(item => {
return (
<Link to={`/detail/${item.sku_id}`} className='item boxsiz' key={item.sku_id}>
<img src={item.goods_images || 'http://static.ichunt.com//dist/res/home/images/goods_default.png'} alt="" />
<div className='gos'>{item.sku_name}</div>
<div className='row bothSide'>
<div className='nam'>{item.brand_name}</div>
<div className='prs'>¥{item.single_price}</div>
</div>
</Link>
)
})
}
</div>
</div>
</>
)
}
export default DetailSection
\ No newline at end of file
.mv-detail-page{
margin-bottom: 47px;
min-height: 500px;
.detail-headers{
min-height: 304px;
padding:40px 35px;
background: #fff;
.goodsimg{
width:222px;
height:222px;
margin-right: 20px;
}
.info{
.box{
height:192px;
width: 420px;
h1{
font-weight: bold;
font-size: 18px;
color: #313131;
line-height: 24px;
margin-bottom: 12px;
}
p{
font-size: 12px;
color: #000000;
line-height: 25px;
max-height: 50px;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
.handle{
.btn{
width: 80px;
height: 30px;
background: #FF9A00;
line-height: 30px;
text-align: center;
color:#fff;
}
}
}
.r{
width: 452px;
min-height: 222px;
background: #FFFCF8;
padding: 10px 50px;
.mb23{
margin-bottom: 24px;
}
.items{
width: 50%;
font-size: 12px;
color: #000000;
line-height: 25px;
span{
width:50%;
}
}
}
}
.detail-section{
margin-top: 20px;
.secl{
width: 978px;
min-height: 330px;
background: #FFFFFF;
padding:30px;
.lilist-box {
border-top: 1px solid #e5e5e5;
font-size : 14px;
color:#313131;
flex-shrink: 0;
flex-wrap: wrap;
border-left: 1px solid #e5e5e5;
p {
line-height : 36px;
width : 50%;
box-sizing: border-box;
height : 36px;
border-right : 1px solid #e5e5e5;
border-bottom : 1px solid #e5e5e5;
overflow : hidden;
text-overflow: ellipsis;
white-space : nowrap;
b {
width : 130px;
float : left;
display : block;
border-right : 1px solid #e5e5e5;
padding-left : 20px;
background : #F5F5F5;
margin-right : 1px;
overflow : hidden;
text-overflow: ellipsis;
white-space : nowrap;
}
span {
padding-left: 10px;
}
.ple0 span {
padding-left: 0px !important;
}
}
}
.goods-mask {
height: 60px;
line-height: 30px;
color: #313131;
font-size: 14px;
div {
width: 130px;
float: left;
border-right: 1px solid #e5e5e5;
border-left: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
padding-left: 20px;
background: #F5F5F5;
height: 90px;
}
h4 {
background: #fff;
width: 745px;
height: 90px;
padding-left: 10px;
padding-right: 10px;
border-right: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
}
}
.secr{
.item{
padding: 34px 18px;
width: 233px;
height: 330px;
transition: all 0.5s;
background: #fff;
display: block;
margin-bottom: 20px;
&:last-child{margin-bottom: 0px;}
&:hover{
box-shadow: 4px 6px 7px 1px rgba(154,151,149,0.18);
transform: translateY(-1px);
}
img{
width: 150px;
height: 109px;
display: block;
margin: 0 auto;
margin-bottom: 60px;
}
.gos{
font-size: 14px;
color: #000000;
line-height: 25px;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
height:50px;
margin-bottom: 30px;
}
.nam{
font-weight: normal;
font-size: 16px;
color: #000000;
line-height: 18px;
text-overflow: ellipsis;
overflow: hidden;
height:18px;
max-width: 110px;
}
.prs{
font-size: 16px;
color: #FF0006;
line-height: 18px;
}
}
}
}
.datanos{
background: #fff;
padding:80px 0;
img{
height:296px;
width:360px;
display: block;
margin:0 auto;
}
}
}
\ No newline at end of file
.mv-detail-page{margin-bottom:47px;min-height:500px}.mv-detail-page .detail-headers{min-height:304px;padding:40px 35px;background:#fff}.mv-detail-page .detail-headers .goodsimg{width:222px;height:222px;margin-right:20px}.mv-detail-page .detail-headers .info .box{height:192px;width:420px}.mv-detail-page .detail-headers .info .box h1{font-weight:bold;font-size:18px;color:#313131;line-height:24px;margin-bottom:12px}.mv-detail-page .detail-headers .info .box p{font-size:12px;color:#000000;line-height:25px;max-height:50px;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.mv-detail-page .detail-headers .info .handle .btn{width:80px;height:30px;background:#FF9A00;line-height:30px;text-align:center;color:#fff}.mv-detail-page .detail-headers .r{width:452px;min-height:222px;background:#FFFCF8;padding:10px 50px}.mv-detail-page .detail-headers .r .mb23{margin-bottom:24px}.mv-detail-page .detail-headers .r .items{width:50%;font-size:12px;color:#000000;line-height:25px}.mv-detail-page .detail-headers .r .items span{width:50%}.mv-detail-page .detail-section{margin-top:20px}.mv-detail-page .detail-section .secl{width:978px;min-height:330px;background:#FFFFFF;padding:30px}.mv-detail-page .detail-section .secl .lilist-box{border-top:1px solid #e5e5e5;font-size:14px;color:#313131;flex-shrink:0;flex-wrap:wrap;border-left:1px solid #e5e5e5}.mv-detail-page .detail-section .secl .lilist-box p{line-height:36px;width:50%;box-sizing:border-box;height:36px;border-right:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mv-detail-page .detail-section .secl .lilist-box p b{width:130px;float:left;display:block;border-right:1px solid #e5e5e5;padding-left:20px;background:#F5F5F5;margin-right:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mv-detail-page .detail-section .secl .lilist-box p span{padding-left:10px}.mv-detail-page .detail-section .secl .lilist-box p .ple0 span{padding-left:0px !important}.mv-detail-page .detail-section .secl .goods-mask{height:60px;line-height:30px;color:#313131;font-size:14px}.mv-detail-page .detail-section .secl .goods-mask div{width:130px;float:left;border-right:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;padding-left:20px;background:#F5F5F5;height:90px}.mv-detail-page .detail-section .secl .goods-mask h4{background:#fff;width:745px;height:90px;padding-left:10px;padding-right:10px;border-right:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.mv-detail-page .detail-section .secr .item{padding:34px 18px;width:233px;height:330px;transition:all .5s;background:#fff;display:block;margin-bottom:20px}.mv-detail-page .detail-section .secr .item:last-child{margin-bottom:0px}.mv-detail-page .detail-section .secr .item:hover{box-shadow:4px 6px 7px 1px rgba(154,151,149,0.18);transform:translateY(-1px)}.mv-detail-page .detail-section .secr .item img{width:150px;height:109px;display:block;margin:0 auto;margin-bottom:60px}.mv-detail-page .detail-section .secr .item .gos{font-size:14px;color:#000000;line-height:25px;word-break:break-all;text-overflow:ellipsis;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;height:50px;margin-bottom:30px}.mv-detail-page .detail-section .secr .item .nam{font-weight:normal;font-size:16px;color:#000000;line-height:18px;text-overflow:ellipsis;overflow:hidden;height:18px;max-width:110px}.mv-detail-page .detail-section .secr .item .prs{font-size:16px;color:#FF0006;line-height:18px}.mv-detail-page .datanos{background:#fff;padding:80px 0}.mv-detail-page .datanos img{height:296px;width:360px;display:block;margin:0 auto}
\ No newline at end of file
import './index.min.css'
import DetailHead from './components/DetailHead';
import DetailSection from './components/DetailSection';
import BreadNav from '../../components/BreadNav';
import { useNavigate, useParams } from 'react-router-dom';
import useRequest from '../../hooks/useRequest';
import { useEffect, useRef, useState } from 'react';
import type { DetailResponseType } from './types'
const GoodsDetail = () => {
const navigate = useNavigate()
const isReq=useRef(0)
const params = useParams()
const [detailData, setDetailData] = useState<DetailResponseType>()
const { request: detailRequest } = useRequest<DetailResponseType>({ manual: true })
useEffect(() => {
isReq.current=0
detailRequest({ url: '/api/goodsSku/getGoodsSkuDetail', params: { sku_id: params.sku_id } }).then(res => {
if (res?.code === 0) {
setDetailData(res)
// if( res?.data?.sku_info===null){
// navigate('/404')
// }
} else {
// navigate('/404')
}
isReq.current=1
})
}, [detailRequest, params.sku_id, navigate])
return (
<>
<div className="mv-detail-page">
{
detailData && detailData.data?.sku_info ?
<>
<BreadNav > <strong>{detailData.data?.sku_info?.sku_name}</strong></BreadNav>
<DetailHead {...detailData} />
<DetailSection {...detailData} />
</>
:
<>
{
isReq.current===1&&
<>
<BreadNav > <strong>找不到型号数据</strong></BreadNav>
<div className='datanos w1226'>
<img src={require('../../images/p404.png')} alt="" />
</div>
</>
}
</>
}
</div>
</>
)
}
export default GoodsDetail
\ No newline at end of file
No preview for this file type
No preview for this file type
No preview for this file type
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 sign in to comment