Commit f63ba8f5 authored by GuanHua's avatar GuanHua

feat:商城页面开发

parent 06aa5755
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "输入程序名称,例如 ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
}
]
}
\ No newline at end of file
const shopRoute = {
const mallRoute = {
path: '/',
component: '@/pages/lxMall/layouts/LXMallLayout',
routes: [
{
// 首页
path: `/`,
name: 'home',
key: 'home',
name: 'mallHome',
key: 'mallHome',
component: '@/pages/lxMall/index',
},
{
// 商品商城
path: `/commodity`,
name: 'mallCommodity',
key: 'mallCommodity',
component: '@/pages/lxMall/commodity',
},
{
// 在线求购
path: `/buy`,
name: 'onlineshopping',
key: 'onlineshopping',
component: '@/pages/lxMall/commodity',
},
{
// 积分商城
path: `/pointsMall`,
name: 'pointsMall',
key: 'pointsMall',
component: '@/pages/lxMall/commodity',
},
{
// 店铺
path: `/shops`,
name: 'shops',
key: 'shops',
component: '@/pages/lxMall/commodity',
},
{
// 资讯
path: `/information`,
name: 'home',
key: 'home',
component: '@/pages/index',
path: `/infomation`,
name: 'infomation',
key: 'infomation',
component: '@/pages/lxMall/commodity',
},
],
}
export default shopRoute
\ No newline at end of file
export default mallRoute
\ No newline at end of file
import memberCenterRoute from './routes'
import shopRoute from './mallRoutes'
import mallRoute from './mallRoutes'
import shopRoute from './shopRoutes'
/**
* @description 路由配置页, 更多配置可查看 https://umijs.org/zh-CN/docs/routing#routes
......@@ -34,6 +35,7 @@ const router = [
},
memberCenterRoute,
shopRoute,
mallRoute,
{
component: '@/pages/404',
},
......
const shopRoute = {
path: '/shop',
component: '@/pages/lxMall/layouts/LXShopLayout',
routes: [
{
// 店铺(渠道商城)
path: `/shop`,
name: 'shopHome',
key: 'shopHome',
component: '@/pages/lxMall/shop',
},
{
// 商品商城
path: `/shop/commodity`,
name: 'shopCommodity',
key: 'shopCommodity',
component: '@/pages/lxMall/commodity',
},
{
// 商品详情
path: `/shop/commodity/detail`,
name: 'commodityDetail',
key: 'commodityDetail',
hide: true,
component: '@/pages/lxMall/commodityDetail',
},
],
}
export default shopRoute
\ No newline at end of file
......@@ -40,11 +40,13 @@
"qrcode": "^1.4.4",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-fontawesome": "^1.7.1",
"react-image-crop": "^8.6.4",
"react-reconciler": "^0.25.1",
"rgbaster": "^2.1.1",
"typescript": "^3.9.7",
"umi": "^3.2.0",
"video-react": "^0.14.1",
"yorkie": "^2.0.0"
},
"devDependencies": {
......
This diff is collapsed.
.input_number {
height: 30px;
width: 120px;
display: flex;
border: 1px solid rgba(235, 236, 240, 1);
line-height: 30px;
&_input {
width: 60px;
border: none;
outline: none;
line-height: 30px;
text-align: center;
border-left: 1px solid rgba(235, 236, 240, 1);
border-right: 1px solid rgba(235, 236, 240, 1);
}
&_item {
width: 30px;
text-align: center;
cursor: pointer;
color: #333333;
&.disable {
color: #EBECF0;
}
}
}
\ No newline at end of file
import React from 'react'
import { MinusOutlined, PlusOutlined } from '@ant-design/icons'
import cx from 'classnames'
import './index.less'
interface InputNumberPropsType {
value: number;
onChange: Function;
}
const InputNumber: React.FC<InputNumberPropsType> = (props) => {
const { value, onChange } = props
const handleReduce = () => {
if (value > 1) {
onChange(Number(value) - 1)
}
}
const handleAdd = () => {
onChange(Number(value) + 1)
}
const handleChange = (e) => {
const { value } = e.target;
const reg = /^\d*?$/;
if (reg.test(value)) {
onChange(value)
}
}
const handleBlur = (e) => {
const { value } = e.target;
if (value === "") {
onChange(1)
}
}
return (
<div className="input_number">
<div className={cx("input_number_item reduce", value <= 1 ? 'disable' : '')} onClick={handleReduce}><MinusOutlined /></div>
<input className="input_number_input" value={value} onChange={handleChange} onBlur={handleBlur} />
<div className="input_number_item add" onClick={handleAdd}><PlusOutlined /></div>
</div>
)
}
export default InputNumber
......@@ -84,7 +84,7 @@ h6 {
}
.padLeft0 {
padding-left: 0!important;
padding-left: 0 !important;
}
// 公共状态 圆点
......@@ -102,6 +102,12 @@ h6 {
background-color: @status-stop; // 停用
}
.mall_container {
width: 1200px;
position: relative;
margin: 0 auto;
}
.commonStatusModify {
.commonStatus();
background-color: @status-modify; // 已修改
......
......@@ -8,6 +8,14 @@
export default {
'menu.welcome': '欢迎',
'menu.home': '首页',
'menu.mallHome': '首页',
'menu.shopHome': '首页',
'menu.mallCommodity': '商品商城',
'menu.shopCommodity': '商品',
'menu.onlineshopping': '在线求购',
'menu.pointsMall': '积分商城',
'menu.shops': '店铺',
'menu.infomation': '资讯',
'menu.admin': '管理页',
'menu.admin.sub-page': '二级管理页',
'menu.login': '登录',
......
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>God-Template</title>
<title>瓴犀开放平台</title>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
</head>
<body>
<div id="root"></div>
</body>
</html>
\ No newline at end of file
body {
background-color: #ffffff;
}
.commodity {
.commodity_container {
display: flex;
margin-top: 20px;
.commodity_main {
flex: 1;
.banner {
height: 160px;
overflow: hidden;
&>img {
width: 100%;
}
}
.tool_bar {
display: flex;
height: 48px;
width: 100%;
margin-top: 20px;
.tool_bar_left {
display: flex;
align-items: center;
.tool_bar_filter_item {
display: flex;
align-items: center;
color: #666666;
margin-right: 30px;
font-size: 12px;
cursor: pointer;
&>.icon {
width: 20px;
height: 20px;
display: inline-block;
line-height: 1;
&>img {
width: 20px;
height: 20px;
}
}
.price_filter_box {
display: flex;
flex-direction: column;
margin-left: 6px;
&>.icon {
font-size: 12px;
color: #CCCCCC;
&:last-child {
margin-top: -4px;
}
}
}
}
}
.tool_bar_right {
margin-left: auto;
display: flex;
align-items: center;
font-size: 12px;
.count {
color: #999999;
&>label {
color: #333300;
margin: 0 2px;
}
}
&>.icon {
color: #CCCCCC;
margin-left: 25px;
font-size: 22px;
cursor: pointer;
&.active {
color: #333333;
}
}
}
}
.filter_bar {
margin-top: 7px;
display: flex;
align-items: center;
.filter_bar_left {
display: flex;
align-items: center;
font-size: 12px;
padding-left: 10px;
&_text {
color: #3A3A3A;
cursor: pointer;
}
&_split {
height: 16px;
width: 1px;
background-color: #E5E5E5;
margin: 0 15px;
}
}
.filter_bar_list {
display: flex;
margin-left: 30px;
.filter_bar_list_item {
height: 20px;
line-height: 20px;
padding: 0 5px;
background-color: #F5F5F5;
font-size: 12px;
color: #333333;
border-radius: 4px;
margin-right: 15px;
// margin-bottom: 8px;
&_text {
&>b {
margin-left: 5px;
color: #D32F2F;
}
}
&_icon {
margin-left: 5px;
cursor: pointer;
}
}
}
}
.pagination_wrap {
margin-top: 60px;
text-align: right;
.ant-pagination-item {
&:hover,
&:active {
border-color: var(--mall_main_color);
&>a {
color: var(--mall_main_color);
}
}
}
.ant-pagination-item-active {
background-color: var(--mall_main_color);
border-color: var(--mall_main_color);
&>a {
color: #ffffff;
}
}
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import { CaretUpOutlined, CaretDownOutlined, UnorderedListOutlined, AppstoreOutlined, CloseOutlined } from '@ant-design/icons'
import Filter from '../components/Filter'
import cx from 'classnames'
import { Pagination } from 'antd'
import CommodityList from './list';
import bannerImg from '@/assets/imgs/banner_2.png'
import arrowDownIcon from '@/assets/imgs/arrow_down.png'
import arrowDownActiveIcon from '@/assets/imgs/arrow_down_active.png'
import './index.less'
const Commodity: React.FC = () => {
const [showType, setShowType] = useState<number>(1) // 展示方式:1:矩阵排列; 2:列表排列
return (
<div className="commodity">
<div className="mall_container">
<div className="commodity_container">
<Filter />
<div className="commodity_main">
<div className="banner">
<img src={bannerImg} />
</div>
<div className="tool_bar">
<div className="tool_bar_left">
<div className="tool_bar_filter_item">
<span>销量</span>
<i className="icon">
<img src={arrowDownIcon} />
</i>
</div>
<div className="tool_bar_filter_item">
<span>信用</span>
<i className="icon">
<img src={arrowDownIcon} />
</i>
</div>
<div className="tool_bar_filter_item">
<span>价格</span>
<div className="price_filter_box">
<CaretUpOutlined className="icon" />
<CaretDownOutlined className="icon" />
</div>
</div>
</div>
<div className="tool_bar_right">
<div className="count">
<span></span>
<label>1,234</label>
<span>个商品</span>
</div>
<AppstoreOutlined className={cx("icon", showType === 1 ? 'active' : '')} onClick={() => setShowType(1)} />
<UnorderedListOutlined className={cx("icon", showType === 2 ? 'active' : '')} onClick={() => setShowType(2)} />
</div>
</div>
<div className="filter_bar">
<div className="filter_bar_left">
<div className="filter_bar_left_text">保存为常用筛选</div>
<div className="filter_bar_left_split"></div>
<div className="filter_bar_left_text">重置</div>
</div>
<div className="filter_bar_list">
<div className="filter_bar_list_item">
<span className="filter_bar_list_item_text">黄牛皮</span>
<CloseOutlined className="filter_bar_list_item_icon" />
</div>
<div className="filter_bar_list_item">
<span className="filter_bar_list_item_text">3M</span>
<CloseOutlined className="filter_bar_list_item_icon" />
</div>
<div className="filter_bar_list_item">
<span className="filter_bar_list_item_text">最低<b>¥179</b></span>
<CloseOutlined className="filter_bar_list_item_icon" />
</div>
</div>
</div>
<CommodityList showType={showType} />
<div className="pagination_wrap">
<Pagination showQuickJumper showSizeChanger={false} defaultCurrent={1} total={100} />
</div>
</div>
</div>
</div>
</div>
)
}
export default Commodity
.commodity_list {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
&.column {
flex-direction: column;
}
&.row {
flex-direction: row;
}
&_item {
width: 25%;
padding: 20px 10px 0 10px;
&.column {
width: 100%;
padding: 0;
margin-bottom: 15px;
.goods_img {
display: inline-block;
width: 120px;
height: 120px;
}
.info_box {
display: inline-block;
margin-left: 20px;
vertical-align: top;
padding-top: 0;
.info_box_content {
display: flex;
align-items: center;
.name {
color: #333333;
font-size: 14px;
width: 400px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.price {
width: 160px;
font-size: 18px;
color: #D32F2F;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&>span {
font-size: 14px;
}
}
}
.shopname {
color: #999999;
font-size: 12px;
margin-top: 5px;
}
.tags_list {
padding: 0;
margin: 0;
margin-top: 10px;
&_item {
display: inline-block;
list-style: none;
color: #999999;
font-size: 12px;
margin-right: 20px;
}
}
.count {
margin-top: 0;
}
}
}
&.row {
&:hover {
.info_box .company_info {
display: block;
}
}
}
&.empty {
background: #f5f5f5;
}
a {
outline: none;
}
.info_box {
position: relative;
padding-top: 15px;
.company_info {
position: absolute;
display: none;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ffffff;
}
}
.goods_img {
width: 220px;
height: 220px;
overflow: hidden;
margin: 0 auto;
&>img {
height: 100%;
display: block;
margin: 0 auto;
}
}
.goods_name {
font-size: 12px;
color: #333333;
text-align: left;
margin-top: 12px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
word-wrap: break-word;
word-break: break-all;
}
.count {
font-size: 12px;
color: #999999;
margin-top: 12px;
}
.credit {
color: #999999;
font-size: 14px;
margin-top: 15px;
line-height: 20px;
&_icon {
width: 20px;
height: 20px;
margin-right: 5px;
}
}
.goods_price {
color: var(--mall_main_color);
line-height: 16px;
display: flex;
font-weight: bold;
align-items: center;
font-size: 18px;
&>span {
font-size: 14px;
font-weight: 400;
}
}
}
}
\ No newline at end of file
import React from 'react'
import cx from 'classnames'
import creditIcon from '@/assets/imgs/credit_icon.png'
import './list.less'
interface CommodityListPropsType {
showType: number
}
const CommodityList: React.FC<CommodityListPropsType> = (props) => {
const { showType } = props
let dataList = []
for (let i = 0; i < 20; i++) {
dataList.push(i)
}
const renderItem = () => {
if (showType === 1) {
return (
<>
{
dataList.map((item, index) => (
<div key={item} className="commodity_list_item row">
<a href={`/shop/commodity/detail?id=asdjflewjfe&type=prompt`}>
<div className="goods_img">
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="info_box">
<div className="goods_price">
<span></span>79.00
</div>
<div className="goods_name">0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软硬度适中偏软软…</div>
<div className="count">已售: 3,230</div>
<div className="company_info">
<div className="goods_name">温州市龙昌皮业有限公司</div>
<div className="credit">
<img className="credit_icon" src={creditIcon} />
<span>1288</span>
</div>
</div>
</div>
</a>
</div>
))
}
</>
)
} else {
return (
<>
{
dataList.map((item, index) => (
<div key={item} className="commodity_list_item column">
<a href={`/shop/commodity/detail?id=asdjflewjfe&type=prompt`}>
<div className="goods_img">
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="info_box">
<div className="info_box_content">
<div className="name">0.8-1.0mm黑色手折纹胎水牛皮</div>
<div className="price"><span></span>79.00</div>
<div className="count">已售: 3,230</div>
</div>
<ul className="tags_list">
<li className="tags_list_item">黄牛头皮层自然摔纹</li>
<li className="tags_list_item">硬度适中偏软</li>
<li className="tags_list_item">手感舒适</li>
</ul>
<div className="credit">
<img className="credit_icon" src={creditIcon} />
<span>1288</span>
</div>
<div className="shopname">温州市龙昌皮业有限公司</div>
</div>
</a>
</div>
))
}
</>
)
}
}
return (
<div className={cx("commodity_list", showType === 2 ? 'column' : 'row')}>
{
renderItem()
}
</div>
)
}
export default CommodityList
.browse_records {
width: 140px;
border: 1px solid rgba(245, 245, 245, 1);
.browse_records_title {
display: flex;
align-items: center;
justify-content: center;
padding: 12px 0;
&_line {
display: block;
width: 20px;
height: 1px;
background-color: #EEEEEE;
}
&_text {
color: #999;
font-size: 12px;
margin: 0 5px;
line-height: 17px;
}
}
.browse_records_product_list {
&_item {
padding: 0 15px;
margin-bottom: 10px;
.product_img_box {
height: 110px;
width: 110px;
overflow: hidden;
&>img {
display: block;
// height: 100%;
width: 100%;
margin: 0 auto;
}
}
.product_price {
font-size: 12px;
color: #333333;
text-align: center;
margin-top: 5px;
}
}
}
.carousel_wrap {
position: relative;
.common_arrow_btn {
position: absolute;
bottom: 10px;
display: block;
color: #999999;
cursor: pointer;
z-index: 99;
width: 20px;
height: 20px;
&.next {
right: 16px;
}
&.prev {
left: 16px;
}
}
}
.ant-carousel .slick-slide {
text-align: center;
height: 460px;
overflow: hidden;
}
.ant-carousel .slick-dots li {
width: 4px;
height: 4px;
background-color: #CCCCCC;
&.slick-active {
background-color: #D32F2F;
}
}
.ant-carousel .slick-dots li.slick-active button {
background-color: #D32F2F;
}
.ant-carousel .slick-dots-bottom {
bottom: 6px;
}
}
\ No newline at end of file
import React, { useRef } from 'react'
import { Carousel } from 'antd'
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import './index.less'
interface BrowseRecordsPropsType {
}
const BrowseRecords: React.FC<BrowseRecordsPropsType> = () => {
const actionRef = useRef<any>()
const product_list = [
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
price: '19.00'
},
]
const arrGroup = (array, subGroupLength) => {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, index += subGroupLength));
}
return newArray;
}
const new_product_list = arrGroup(product_list, 3)
return (
<div className="browse_records">
<div className="browse_records_title">
<span className="browse_records_title_line"></span>
<span className="browse_records_title_text">买家还在看</span>
<span className="browse_records_title_line"></span>
</div>
<div className="carousel_wrap">
<Carousel ref={actionRef}>
{
new_product_list.map((item, index) => (
<div key={`product_list_${index}`} className="browse_records_product_list">
{
item.map((childItem, childIndex) => (
<div key={`browse_records_product_list_item_${childIndex}`} className="browse_records_product_list_item">
<div className="product_img_box">
<img src={childItem.imgUrl} />
</div>
<div className="product_price">{childItem.price}</div>
</div>
))
}
</div>
))
}
</Carousel>
<LeftOutlined className="common_arrow_btn prev" onClick={() => actionRef.current.prev()} />
<RightOutlined className="common_arrow_btn next" onClick={() => actionRef.current.next()} />
</div>
</div>
)
}
export default BrowseRecords
.exhibition {
width: 380px;
.exhibition_img_container {
width: 100%;
height: 380px;
overflow: hidden;
&>img {
width: 100%;
display: block;
}
}
.exhibition_toolbar {
height: 60px;
width: 100%;
display: flex;
margin-top: 20px;
.exhibition_tool_item {
width: 15px;
height: 60px;
background: rgba(245, 245, 245, 1);
line-height: 60px;
text-align: center;
color: #cccccc;
cursor: pointer;
}
.exhibition_list_contaner {
position: relative;
flex: 1;
overflow: hidden;
.exhibition_list {
position: relative;
white-space: nowrap;
transition: all .3s;
&_item {
position: relative;
display: inline-block;
width: 60px;
height: 60px;
overflow: hidden;
margin: 0 5px;
cursor: pointer;
&:hover {
&::before {
opacity: 1;
}
&.active {
&::before {
opacity: 0;
}
}
}
&::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, .7);
z-index: 5;
opacity: 0;
transition: all .3s;
cursor: pointer;
}
&>img {
width: 100%;
display: block;
}
}
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import cx from 'classnames'
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import './index.less'
interface ExhibitionPropsType {
}
const imgList = [
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-5.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-3.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-2.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1.jpg"
}
]
const Exhibition: React.FC<ExhibitionPropsType> = () => {
const [previewImg, setPreviewImg] = useState<any>(imgList[0])
const [offSetLeft, setOffSetLeft] = useState<number>(0)
const handlePrev = () => {
if (offSetLeft < 0) {
setOffSetLeft(offSetLeft + 70)
}
}
const handleNext = () => {
let imgLength = imgList.length
let maxDistance = (imgLength - 5) * 70
if (maxDistance > Math.abs(offSetLeft)) {
setOffSetLeft(offSetLeft - 70)
}
}
return (
<div className="exhibition">
<div className="exhibition_img_container">
<img src={previewImg.url} />
</div>
<div className="exhibition_toolbar">
<div className="exhibition_tool_item prev" onClick={() => handlePrev()}><LeftOutlined /></div>
<div className="exhibition_list_contaner">
<div className="exhibition_list" style={{ left: offSetLeft }}>
{
imgList.map((item, index) => (
<div key={index} className={cx("exhibition_list_item", previewImg.url === item.url ? 'active' : '')} onClick={() => setPreviewImg(item)}>
<img src={item.url} />
</div>
))
}
</div>
</div>
<div className="exhibition_tool_item next" onClick={() => handleNext()}><RightOutlined /></div>
</div>
</div>
)
}
export default Exhibition
.interested {
border: 1px solid rgba(245, 245, 245, 1);
width: 190px;
.interested_title {
font-size: 14px;
color: #333333;
padding: 10px 20px;
font-weight: bold;
}
.interested_product_list {
&_item {
padding: 0 20px;
margin-bottom: 8px;
&_img_box {
height: 150px;
overflow: hidden;
&>img {
width: 100%;
}
}
&_name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999999;
font-size: 12px;
margin-top: 5px;
}
&_price {
color: #D32F2F;
margin-top: 6px;
font-size: 14px;
&>span {
font-size: 12px;
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import './index.less'
const Interested: React.FC = () => {
return (
<div className="interested">
<div className="interested_title">最近销售</div>
<div className="interested_product_list">
<a href="/shop/commodity/detail?id=asdjflewjfe&type=prompt">
<div className="interested_product_list_item">
<div className="interested_product_list_item_img_box">
<img src="https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg" />
</div>
<div className="interested_product_list_item_name">0.8-1.0mm黑色手折纹胎…</div>
<div className="interested_product_list_item_price"><span></span> 79.00</div>
</div>
</a>
<a href="/shop/commodity/detail?id=asdjflewjfe&type=prompt">
<div className="interested_product_list_item">
<div className="interested_product_list_item_img_box">
<img src="https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg" />
</div>
<div className="interested_product_list_item_name">0.8-1.0mm黑色手折纹胎…</div>
<div className="interested_product_list_item_price"><span></span> 79.00</div>
</div>
</a>
</div>
</div>
)
}
export default Interested
.comment {
margin-top: 20px;
.comment_title {
height: 40px;
background-color: #F5F5F5;
padding-left: 20px;
font-size: 14px;
color: #333333;
font-weight: bold;
line-height: 40px;
}
.favorable_comments {
padding: 30px 17px;
&_title {
font-size: 12px;
color: #999999;
}
&>span {
font-size: 32px;
color: #D32F2F;
}
&>i {
margin-left: 6px;
font-size: 14px;
color: #D32F2F;
}
}
.common_count {
display: flex;
height: 32px;
align-items: center;
background-color: #F5F5F5;
font-size: 12px;
color: #666666;
&_item {
margin-left: 20px;
cursor: pointer;
&.active {
color: #D32F2F;
}
}
}
.comment_list {
&_item {
padding: 20px 0 20px 20px;
border-bottom: 1px solid #F5F5F5;
display: flex;
&_left {
position: relative;
font-size: 12px;
width: 257px;
.user_avatar {
&>img {
width: 30px;
height: 30px;
}
}
.user_name {
margin-top: 6px;
}
.user_type {
color: #F8EDAF;
display: inline-block;
background-color: #333333;
height: 16px;
font-size: 12px;
line-height: 16px;
padding: 0 3px;
text-align: center;
margin-top: 4px;
}
}
&_right {
position: relative;
flex: 1;
margin-left: 20px;
.comment_rate {
font-size: 15px;
}
.comment_content {
font-size: 12px;
color: #333333;
margin-top: 4px;
}
.comment_date {
font-size: 12px;
color: #999999;
margin-top: 20px;
}
}
}
}
.pagination_wrap {
margin-top: 20px;
text-align: right;
.ant-pagination-item {
&:hover,
&:active {
border-color: #D32F2F;
&>a {
color: #D32F2F;
}
}
}
.ant-pagination-item-active {
background-color: #D32F2F;
border-color: #D32F2F;
&:hover {
&>a {
color: #ffffff;
}
}
&>a {
color: #ffffff;
}
}
}
}
\ No newline at end of file
import React from 'react'
import cx from 'classnames'
import { Rate, Pagination } from 'antd'
import ImageViewList from '../ImageViewList'
import defaultAvatar from '@/assets/imgs/default_avatar.png'
import './index.less'
const Comment: React.FC = () => {
return (
<div id="comment" className="comment">
<div className="comment_title">交易评价</div>
<div className="favorable_comments">
<div className="favorable_comments_title">好评率</div>
<span>98</span>
<i>%</i>
</div>
<div className="common_count">
<div className={cx("common_count_item", "active")}>全部评价(200+)</div>
<div className="common_count_item">好评(100+)</div>
<div className="common_count_item">中评(99)</div>
<div className="common_count_item">差评(5)</div>
</div>
<div className="comment_list">
<div className="comment_list_item">
<div className="comment_list_item_left">
<div className="user_avatar">
<img src={defaultAvatar} />
</div>
<div className="user_name">温州市****皮具有限公司</div>
<div className="user_type">VIP会员</div>
</div>
<div className="comment_list_item_right">
<Rate className="comment_rate" value={4} disabled />
<div className="comment_content">买的京东那个叫什么三购买的,不错。9块9。洗完澡以后穿着这个再大。听你走来走去也没事,跟家人一起的话穿着这个既文明药物。可以。保持礼貌。</div>
<div className="comment_date">2020-05-20 15:58</div>
</div>
</div>
<div className="comment_list_item">
<div className="comment_list_item_left">
<div className="user_avatar">
<img src={defaultAvatar} />
</div>
<div className="user_name">温州市****皮具有限公司</div>
<div className="user_type">VIP会员</div>
</div>
<div className="comment_list_item_right">
<Rate className="comment_rate" value={4} disabled />
<div className="comment_content">买的京东那个叫什么三购买的,不错。9块9。洗完澡以后穿着这个再大。听你走来走去也没事,跟家人一起的话穿着这个既文明药物。可以。保持礼貌。</div>
<ImageViewList />
<div className="comment_date">2020-05-20 15:58</div>
</div>
</div>
</div>
<div className="pagination_wrap">
<Pagination showQuickJumper={false} showSizeChanger={false} defaultCurrent={1} total={50} />
</div>
</div>
)
}
export default Comment
.image_view_list {
.thumb_img_list {
display: flex;
margin-top: 20px;
&_item {
position: relative;
margin-right: 10px;
cursor: pointer;
border: 1px solid #ffffff;
&.active {
border: 1px solid #D32F2F;
}
&:hover {
&::before {
opacity: 1;
}
&.active {
&::before {
opacity: 0;
}
}
}
&::before {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .25);
z-index: 5;
opacity: 0;
transition: all .3s;
cursor: pointer;
}
&>img {
height: 49px;
width: 49px;
}
}
}
.image_preview_box {
position: relative;
margin-top: 20px;
overflow: hidden;
.image_preview_toolbar {
position: absolute;
display: flex;
font-size: 12px;
color: #ffffff;
padding-top: 10px;
padding-left: 10px;
z-index: 6;
&_item {
height: 17px;
line-height: 17px;
padding: 0 4px;
margin-right: 5px;
cursor: pointer;
background: rgba(0, 0, 0, 0.5);
border-radius: 2px;
&:hover {
background: rgba(0, 0, 0, 0.6);
}
&>.icon {
margin-right: 2px;
}
}
}
&>img {
width: 300px;
height: 300px;
transition: all .3s;
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import { VerticalRightOutlined, FullscreenOutlined, UndoOutlined, RedoOutlined } from '@ant-design/icons'
import cx from 'classnames'
import './index.less'
const ImageViewList = () => {
const [previewImage, setPreviewImage] = useState<number>(-1)
const [rotateZ, setRotateZ] = useState<number>(0)
const imgList = [
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-5.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-3.jpg"
},
{
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-2.jpg"
},
]
const handlePreviewImg = (index: number) => {
if (previewImage !== index) {
setPreviewImage(index)
} else {
setPreviewImage(-1)
setRotateZ(0)
}
}
const handleActions = (action: string) => {
switch (action) {
case 'turnLeft':
setRotateZ(rotateZ - 90)
break
case 'turnRight':
setRotateZ(rotateZ + 90)
break
case 'packUp':
setPreviewImage(-1)
setRotateZ(0)
break
case 'preview':
let el = document.createElement('a')
el.href = imgList[previewImage].url;
el.target = '_blank';
el.click()
break
default:
break
}
}
return (
<div className="image_view_list">
<div className="thumb_img_list">
{
imgList.map((item, index) => (
<div
key={`thumb_img_list_item_${index}`}
className={cx("thumb_img_list_item", previewImage === index ? 'active' : '')}
onClick={() => handlePreviewImg(index)}
>
<img src={item.url} />
</div>
))
}
</div>
{
(previewImage === 0 || previewImage !== -1) && (
<div className="image_preview_box">
<div className="image_preview_toolbar">
<div className="image_preview_toolbar_item" onClick={() => handleActions('packUp')}>
<VerticalRightOutlined className="icon" rotate={90} />
<span>收起</span>
</div>
<div className="image_preview_toolbar_item" onClick={() => handleActions('preview')}>
<FullscreenOutlined className="icon" />
<span>原图</span>
</div>
<div className="image_preview_toolbar_item" onClick={() => handleActions('turnLeft')}>
<UndoOutlined className="icon" />
<span>左转</span>
</div>
<div className="image_preview_toolbar_item" onClick={() => handleActions('turnRight')}>
<RedoOutlined className="icon" />
<span>右转</span>
</div>
</div>
<img src={imgList[previewImage].url} style={{ transform: `rotateZ(${rotateZ}deg)` }} />
</div>
)
}
</div>
)
}
export default ImageViewList
.introduction {
.introduction_list {
display: flex;
flex-wrap: wrap;
padding: 20px;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #F5F5F5;
&_item {
width: 33.33%;
display: flex;
font-size: 12px;
margin-bottom: 10px;
&>.label {
width: 108px;
color: #999999;
overflow: hidden;
}
&>.breif {
color: #333333;
}
}
}
}
\ No newline at end of file
import React from 'react'
import { ScienceTemplate } from './template'
import './index.less'
const Introduction: React.FC = () => {
const data = [
{
label: '主要用途',
value: '皮鞋、皮带、箱包、其他用途'
},
{
label: '皮层',
value: '二层'
},
{
label: '风格',
value: '荔枝纹'
},
{
label: '张幅皮形',
value: '自然张'
},
{
label: '颜色',
value: '黑色、红色、黄色、橙色、咖啡色'
},
{
label: '厚度',
value: '1.0mm ~ 1.5mm'
},
{
label: '产地',
value: '无'
},
{
label: '尺码保障',
value: '83%'
},
{
label: '取样',
value: '无'
},
{
label: '等级',
value: '统级'
},
{
label: '保税',
value: '是'
},
{
label: '备注',
value: '统级'
},
{
label: '编号',
value: '无'
},
{
label: '材质',
value: '无'
},
{
label: '国际色卡',
value: '无'
},
{
label: '手感',
value: '无'
},
{
label: '七天无理由退换货',
value: '无'
},
{
label: '交货地',
value: '无'
},
{
label: '商品状态',
value: '无'
},
]
const renderIntroduction = () => {
let templateName = 'science'
switch (templateName) {
case 'science':
return <ScienceTemplate />
}
}
return (
<div id="introduction" className="introduction">
<div className="introduction_list">
{
data.map((item, index) => (
<div className="introduction_list_item" key={`introduction_list_item_${index}`}>
<div className="label">{item.label}</div>
<div className="breif">{item.value}</div>
</div>
))
}
</div>
{
renderIntroduction()
}
</div>
)
}
export default Introduction
.video_box {
width: 790px;
overflow: hidden;
margin-bottom: 20px;
.video-react .video-react-big-play-button {
border-radius: 50%;
width: 66px;
height: 66px;
line-height: 66px;
border: 1px solid #FFF;
}
&>video {
width: 790px;
height: auto;
}
}
.img_list {
width: 790px;
&>img {
width: 790px;
height: auto;
}
}
\ No newline at end of file
/*
* 科技类商品描述模板
* @Author: ghua
* @Date: 2020-08-01 10:59:17
* @Last Modified by: ghua
* @Last Modified time: 2020-08-01 10:59:17
*/
import React, { Fragment } from 'react'
import { Player, BigPlayButton, ControlBar } from 'video-react'
import "video-react/dist/video-react.css"
import './index.less'
interface ScienceTemplatePropsType {
}
const ScienceTemplate: React.FC<ScienceTemplatePropsType> = () => {
return (
<Fragment>
<div className="video_box">
<Player
poster="https://img.alicdn.com/imgextra/i1/2200692764442/O1CN01OQ5Y9q1igTvAGTpsB_!!2200692764442.jpg"
src="https://media.w3.org/2010/05/sintel/trailer_hd.mp4"
>
<BigPlayButton position="center" />
<ControlBar autoHide={true} />
</Player>
</div>
<div className="img_list">
<img src="https://img.alicdn.com/imgextra/i1/2200692764442/O1CN01OQ5Y9q1igTvAGTpsB_!!2200692764442.jpg" />
</div>
</Fragment>
)
}
export default ScienceTemplate
.recommand {
margin-top: 20px;
.recommand_title {
height: 40px;
line-height: 40px;
background-color: #f5f5f5;
font-size: 14px;
font-weight: bold;
color: #333333;
padding-left: 20px;
}
.recommand_list {
display: flex;
flex-wrap: wrap;
margin: 0 -10px;
&_item {
position: relative;
width: 184px;
margin: 10px;
&_img {
width: 100%;
height: 184px;
overflow: hidden;
&>img {
width: 100%;
height: auto;
}
}
&_name {
margin-top: 10px;
font-size: 12px;
color: #333333;
}
&_price {
font-size: 14px;
color: #D32F2F;
margin-top: 10px;
&>span {
font-size: 12px;
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import './index.less'
const Recommand: React.FC = () => {
const product_list = [
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
{
imgUrl: 'https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-6.jpg',
name: '0.8-1.0mm黑色手折纹胎水牛皮黄牛头层自然摔纹硬度适中偏软…',
price: '19.00'
},
]
return (
<div className="recommand">
<div className="recommand_title">交易评价</div>
<div className="recommand_list">
{
product_list.map((item, index) => (
<a href="/shop/commodity/detail?id=asdjflewjfe&type=prompt" key={`recommand_list_item_${index}`}>
<div className="recommand_list_item">
<div className="recommand_list_item_img">
<img src={item.imgUrl} />
</div>
<div className="recommand_list_item_name">{item.name}</div>
<div className="recommand_list_item_price">
<span></span>
{item.price}
</div>
</div>
</a>
))
}
</div>
</div>
)
}
export default Recommand
.trade_record {
margin-top: 20px;
.trade_record_title {
height: 40px;
line-height: 40px;
background-color: #F5F5F5;
padding-left: 20px;
font-size: 14px;
font-weight: bold;
margin-bottom: 20px;
}
.trade_record_container {
.ant-pagination-item {
&:hover,
&:active {
border-color: #D32F2F;
&>a {
color: #FFF;
}
}
}
.ant-pagination-item-active {
background-color: #D32F2F;
border-color: #D32F2F;
&>a {
color: #ffffff;
}
}
// .ant-pagination-item-active {
// border-color: #D32F2F;
// background-color: #D32F2F;
// color: #ffffff;
// a {
// color: #FFFFFF;
// }
// }
.columns_item {
height: 48px;
display: flex;
flex-direction: column;
justify-content: center;
&_member {
color: #F8EDAF;
background-color: #333333;
height: 16px;
line-height: 16px;
width: 48px;
text-align: center;
margin-top: 4px;
}
}
.ant-table-tbody {
font-size: 12px;
color: #333333;
}
.ant-table-thead>tr>th {
background: #FFFFFF;
font-size: 12px;
padding: 10px 20px;
}
}
}
\ No newline at end of file
import React from 'react'
import { Table } from 'antd'
import './index.less'
const TradeRecord: React.FC = () => {
const columns = [
{
title: '买家',
width: '33%',
render: (_, record: any) => {
return (
<div className="columns_item">
<div className="columns_item_name">{record.name}</div>
{record.type === 1 && <div className="columns_item_member">VIP会员</div>}
</div>
)
}
},
{
title: '成交数量',
dataIndex: 'count',
width: '33%'
},
{
title: '交易时间',
dataIndex: 'date',
width: '33%'
},
]
const mockData = [
{
id: 1,
name: '温州市****皮具有限公司',
count: 30,
date: '2020-05-20 15:58',
type: 1
},
{
id: 2,
name: '温州市****皮具有限公司',
count: 30,
date: '2020-05-20 15:58',
type: 2
},
]
return (
<div id="trade_record" className="trade_record">
<div className="trade_record_title">
交易记录
</div>
<div className="trade_record_container">
<Table rowKey="id" columns={columns} dataSource={mockData} />
</div>
</div>
)
}
export default TradeRecord
.product_description {
&_anchor {
background-color: #F5F5F5;
height: 40px;
padding: 0;
margin: 0;
overflow: hidden;
.buy_now_btn {
position: relative;
background-color: #D32F2F;
color: #FFFFFF;
margin-left: auto;
margin-right: 20px;
height: 32px;
width: 120px;
text-align: center;
line-height: 32px;
right: 0;
bottom: 0;
}
.ant-anchor {
display: flex;
align-items: center;
padding: 0;
.ant-anchor-ink {
display: none;
}
.ant-anchor-link {
padding: 0;
height: 40px;
line-height: 40px;
padding: 0 24px;
&.active {
background-color: #FFFFFF;
border-top: 2px solid #D32F2F;
a {
color: #D32F2F;
}
}
&.ant-anchor-link-active {
background-color: #FFFFFF;
border-top: 2px solid #D32F2F;
a {
color: #D32F2F;
}
}
&:hover {
background-color: #FFFFFF;
border-top: 2px solid #D32F2F;
a {
color: #D32F2F;
}
}
}
}
}
}
\ No newline at end of file
import React, { useState, useEffect } from 'react'
import { Anchor, BackTop } from 'antd'
import Comment from './components/Comment'
import Introduction from './components/Introduction'
import TradeRecord from './components/TradeRecord'
import Recommand from './components/Recommand'
import cx from 'classnames'
import './index.less'
const { Link } = Anchor
const ProductDescription: React.FC = () => {
const [currentAnchor, setCurrentAnchor] = useState<string>("#introduction")
const handleAnchorChange = (currentActiveLink: string) => {
if (currentActiveLink) {
console.log(currentActiveLink, "currentActiveLink")
setCurrentAnchor(currentActiveLink)
} else {
console.log(currentActiveLink, "currentActiveLink")
}
}
return (
<div className="product_description" id="product_description">
<Anchor
className="product_description_anchor"
targetOffset={120}
onChange={handleAnchorChange}
>
<Link className={cx(currentAnchor === "#introduction" ? 'active' : '')} href="#introduction" title="产品简介" />
<Link href="#trade_record" title="交易记录(2)" />
<Link href="#comment" title="交易评价(96)" />
<BackTop className="buy_now_btn" visibilityHeight={800} >立即订购</BackTop>
</Anchor>
<Introduction />
<TradeRecord />
<Comment />
<Recommand />
</div>
)
}
export default ProductDescription
.shop_info {
position: relative;
width: 190px;
padding: 0 10px;
padding-bottom: 15px;
margin-bottom: 20px;
border: 1px solid rgba(245, 245, 245, 1);
background: linear-gradient(180deg, rgba(255, 245, 203, 1) 0%, rgba(255, 253, 244, 1) 100%);
.shop_info_title {
display: flex;
align-items: center;
justify-content: center;
height: 47px;
&_split {
width: 40px;
height: 1px;
background-color: #F2C17C;
}
&_text {
color: #EA8000;
margin: 0 15px;
}
}
.shop_name {
font-size: 12px;
color: #333333;
margin-bottom: 10px;
font-weight: bold;
}
.shop_about {
display: flex;
&_item {
flex: 1;
display: flex;
align-items: center;
&>span {
font-size: 14px;
color: #333333;
line-height: 20px;
&.red {
color: #D32F2F;
margin-right: 4px;
}
}
&>.icon {
position: relative;
top: -1px;
overflow: hidden;
margin-right: 5px;
&>img {
width: 20px;
height: 20px;
}
}
}
}
.dashed_split {
margin: 15px 0;
width: 100%;
border-top: 1px dashed #F2C17C;
height: 0;
}
.shop_info_list {
margin-top: 10px;
&_item {
display: flex;
font-size: 12px;
color: #333333;
align-items: center;
&:not(:last-child) {
margin-bottom: 5px;
}
&>.breif {
.star {
font-size: 15px;
line-height: 15px;
}
.certified {
color: #00B37A;
}
}
&>.label {
width: 60px;
}
}
}
.shop_info_btn_group {
display: flex;
.shop_info_btn {
flex: 1;
height: 32px;
background-color: #FFFFFF;
border: 1px solid rgba(229, 229, 229, 1);
color: #333333;
font-size: 12px;
line-height: 32px;
text-align: center;
cursor: pointer;
&:hover {
background-color: #f5f5f5;
}
&:last-child {
margin-left: 6px;
}
}
}
.apply_member_btn {
margin-top: 15px;
width: 100%;
height: 32px;
background-color: #D32F2F;
color: #FFF;
line-height: 32px;
text-align: center;
font-size: 12px;
cursor: pointer;
&:hover {
opacity: .9;
}
}
}
\ No newline at end of file
import React from 'react'
import { Rate } from 'antd'
import shop_icon from '@/assets/imgs/shop_icon.png'
import credit_icon from '@/assets/imgs/credit_icon.png'
import './index.less'
const ShopInfo: React.FC = () => {
return (
<div className="shop_info">
<div className="shop_info_title">
<div className="shop_info_title_split"></div>
<div className="shop_info_title_text">会员认证</div>
<div className="shop_info_title_split"></div>
</div>
<div className="shop_name">温州市龙昌皮具有限公司</div>
<div className="shop_about">
<div className="shop_about_item">
<i className="icon"><img src={shop_icon} /></i>
<span className="red">2</span>
<span></span>
</div>
<div className="shop_about_item">
<i className="icon"><img src={credit_icon} /></i>
<span>1288</span>
</div>
</div>
<div className="shop_info_list">
<div className="shop_info_list_item">
<div className="label">满意度:</div>
<div className="breif"><Rate className="star" count={4} disabled defaultValue={4} /></div>
</div>
<div className="shop_info_list_item">
<div className="label">注册资本:</div>
<div className="breif">5000万元</div>
</div>
<div className="shop_info_list_item">
<div className="label">成立日期:</div>
<div className="breif">2014-09-09</div>
</div>
<div className="shop_info_list_item">
<div className="label">营业执照:</div>
<div className="breif"><span className="certified">[已认证]</span></div>
</div>
</div>
<div className="dashed_split"></div>
<div className="shop_info_btn_group">
<div className="shop_info_btn">进入店铺</div>
<div className="shop_info_btn">收藏本店</div>
</div>
<div className="apply_member_btn">申请成为本店会员</div>
</div>
)
}
export default ShopInfo
.commodity_detail {
position: relative;
&_container {
width: 1200px;
margin: 0 auto;
.commodity_detail_info {
margin-top: 20px;
display: flex;
.product_info_container {
flex: 1;
margin: 0 20px;
.product_info {
.product_info_name {
font-size: 16px;
color: #333333;
font-weight: bold;
line-height: 22px;
}
.product_info_tags {
display: flex;
margin-top: 5px;
&_item {
font-size: 12px;
color: #D32F2F;
margin-right: 20px;
line-height: 20px;
margin-bottom: 5px;
}
}
.prompt_goods_price {
display: flex;
margin-top: 12px;
border-bottom: 1px solid #F5F5F5;
padding-bottom: 17px;
.label {
font-size: 12px;
color: #999999;
width: 102px;
line-height: 12px;
&.price {
padding-top: 5px;
line-height: 32px;
}
&.mprice {
margin-top: 16px;
}
&.count {
margin-top: 10px;
}
}
&_list {
display: flex;
flex: 1;
justify-content: space-between;
padding-right: 90px;
&_item {
padding: 5px 6px;
&.active {
background-color: #FAFAFA;
}
.price {
font-size: 24px;
color: #D32F2F;
line-height: 32px;
}
.member_price {
font-size: 16px;
color: #3A3A3A;
margin-top: 12px;
line-height: 16px;
}
.count {
color: #333333;
font-size: 12px;
line-height: 12px;
margin-top: 10px;
}
}
}
}
.product_info_line {
display: flex;
align-items: center;
margin-top: 20px;
&.mar_top_10 {
margin-top: 10px;
}
&_label {
color: #999999;
font-size: 12px;
width: 110px;
}
&_brief {
&.row {
display: flex;
align-items: center;
}
.text {
font-size: 12px;
color: #333333;
margin-right: 10px;
&.mar_left_10 {
margin-left: 10px;
}
}
.product_info_line_list {
display: flex;
&_item {
position: relative;
height: 32px;
width: 80px;
display: flex;
align-items: center;
border: 1px solid rgba(235, 236, 240, 1);
cursor: pointer;
&.center {
justify-content: center;
}
&.active {
border: 1px solid #D32F2F;
color: #D32F2F;
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: 12px solid #D32F2F;
border-left: 12px solid transparent;
bottom: 0;
right: 0;
z-index: 5;
}
}
&:not(:last-child) {
margin-right: 20px;
}
.imgbox {
overflow: hidden;
margin-right: 10px;
margin-left: 2px;
&>img {
width: 28px;
height: 28px;
}
}
}
}
}
}
.product_info_price {
background-color: #F5F5F5;
margin-top: 20px;
height: 60px;
display: flex;
align-items: center;
padding: 0 22px;
&_text {
font-size: 18px;
font-weight: bold;
color: #D32F2F;
display: flex;
align-items: center;
&>span {
margin-left: 5px;
font-size: 12px;
}
}
&_split {
height: 32px;
width: 1px;
background-color: #E5E5E5;
margin: 0 15px;
}
}
.product_info_btn_group {
display: flex;
margin-top: 16px;
.product_info_btn_item {
margin-right: 20px;
width: 160px;
height: 40px;
background: rgba(211, 47, 47, 0.05);
border: 1px solid rgba(211, 47, 47, 0.2);
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: #D32F2F;
cursor: pointer;
&.buy {
background-color: #D32F2F;
color: #FFF;
border: 1px solid #D32F2F;
;
}
&:hover {
opacity: .8;
}
.btn_icon {
width: 20px;
height: 20px;
margin-right: 5px;
}
}
}
}
}
}
.commodity_detail_body {
display: flex;
margin-top: 30px;
&_left {
width: 190px;
}
&_right {
flex: 1;
margin-left: 10px;
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { Tooltip } from 'antd'
import cx from 'classnames'
import Exhibition from './components/Exhibition'
import BrowseRecords from './components/BrowseRecords'
import Interested from './components/Interested'
import ShopInfo from './components/ShopInfo'
import ProductDescription from './components/ProductDescription'
import InputNumber from '@/components/InputNumber'
import jinhuodanIcon from '@/assets/imgs/jinhuodan.png'
import './index.less'
const CommodityDetail = (props) => {
// type : prompt:现货商品;inquiry:询价商品;integral:积分商品
const { query: { id, type = "prompt" } } = props.location
const COMMODITY_TYPE = {
prompt: 'prompt',
inquiry: 'inquiry',
integral: 'integral'
}
const [buyCount, setBuyCount] = useState<number>(1)
const colorList = [
{
name: '红色',
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1.jpg"
},
{
name: '蓝色',
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-5.jpg"
},
{
name: '白色',
url: "https://woodmartcdn-cec2.kxcdn.com/wp-content/uploads/2016/09/product-furniture-1-3.jpg"
},
]
const typeList = [
{
id: 1,
name: 'XL'
},
{
id: 2,
name: 'XXL'
},
{
id: 3,
name: 'XXXL'
}
]
const renderBtn = () => {
switch (type) {
case 'prompt':
return (
<>
<div className="product_info_btn_item buy">立即订购</div>
<div className="product_info_btn_item add"><img className="btn_icon" src={jinhuodanIcon} />加入进货单</div>
</>
)
case 'inquiry':
return <div className="product_info_btn_item buy">立即询价</div>
case 'integral':
return <div className="product_info_btn_item buy">立即兑换</div>
}
}
return (
<div className="commodity_detail">
<div className="commodity_detail_container">
<div className="commodity_detail_info">
<Exhibition />
<div className="product_info_container">
<div className="product_info">
<div className="product_info_name">0.8-1.0mm黑色手折纹胎水牛皮</div>
<div className="product_info_tags">
<div className="product_info_tags_item">黄牛头皮层自然摔纹</div>
<div className="product_info_tags_item">硬度适中偏软</div>
<div className="product_info_tags_item">手感舒适</div>
</div>
{
type === COMMODITY_TYPE.prompt && (
<div className="prompt_goods_price">
<div className="prompt_goods_price_item">
<div className="label price">价格(CNY)</div>
<div className="label mprice">会员价格(CNY)</div>
<div className="label count">数量(平方英尺)</div>
</div>
<div className="prompt_goods_price_list">
<div className="prompt_goods_price_list_item active">
<div className="price">20.00</div>
<div className="member_price">19.00</div>
<div className="count">1-20</div>
</div>
<div className="prompt_goods_price_list_item">
<div className="price">19.00</div>
<div className="member_price">19.00</div>
<div className="count">21-49</div>
</div>
<div className="prompt_goods_price_list_item">
<div className="price">18.00</div>
<div className="member_price">19.00</div>
<div className="count">50-99</div>
</div>
<div className="prompt_goods_price_list_item">
<div className="price">15.00</div>
<div className="member_price">19.00</div>
<div className="count">≥100</div>
</div>
</div>
</div>
)
}
<div className="product_info_line">
<div className="product_info_line_label">颜色</div>
<div className="product_info_line_brief">
<div className="product_info_line_list">
{
colorList.map((item, index) => (
<div key={`product_info_line_list_item_${index}`} className="product_info_line_list_item">
<div className="imgbox">
<img src={item.url} />
</div>
<span>{item.name}</span>
</div>
))
}
</div>
</div>
</div>
<div className="product_info_line">
<div className="product_info_line_label">尺码</div>
<div className="product_info_line_brief">
<div className="product_info_line_list">
{
typeList.map((item, index) => (
<div key={`product_info_line_list_item_type_${index}`} className={cx("product_info_line_list_item center", index === 0 ? 'active' : '')}>
<span>{item.name}</span>
</div>
))
}
</div>
</div>
</div>
{
type === COMMODITY_TYPE.integral && (
<div className="product_info_line">
<div className="product_info_line_label">所需积分</div>
<div className="product_info_line_brief">
<span className="text">20000分</span>
<Tooltip placement="top" title="可使用平台通用积分或商户积分进行兑换">
<QuestionCircleOutlined />
</Tooltip>
</div>
</div>
)
}
{
type === COMMODITY_TYPE.inquiry ? (
<div className="product_info_line">
<div className="product_info_line_label">库存数量</div>
<div className="product_info_line_brief">
<span className="text">20,000平方英尺</span>
</div>
</div>
) : (
<div className="product_info_line">
<div className="product_info_line_label">{type === COMMODITY_TYPE.prompt ? '购买数量' : '兑换数量'}</div>
<div className="product_info_line_brief row">
<InputNumber value={buyCount} onChange={(value) => setBuyCount(value)} />
<span className="text mar_left_10">平方英尺</span>
<span className="text mar_left_10">(库存20,000平方英尺)</span>
</div>
</div>
)
}
{
type === 'prompt' && (
<div className="product_info_price">
<div className="product_info_price_text">3<span>平方英尺</span></div>
<div className="product_info_price_split"></div>
<div className="product_info_price_text">69.70<span></span></div>
</div>
)
}
<div className="product_info_btn_group">
{
renderBtn()
}
</div>
<div className="product_info_line">
<div className="product_info_line_label">支付方式</div>
<div className="product_info_line_brief">
<span className="text">线上支付</span>
<span className="text">线下支付</span>
<span className="text">授信支付</span>
<span className="text">货到付款</span>
</div>
</div>
<div className="product_info_line mar_top_10">
<div className="product_info_line_label">配送方式</div>
<div className="product_info_line_brief">
<span className="text">物流</span>
</div>
</div>
</div>
</div>
<BrowseRecords />
</div>
<div className="commodity_detail_body">
<div className="commodity_detail_body_left">
<ShopInfo />
<Interested />
</div>
<div className="commodity_detail_body_right">
<ProductDescription />
</div>
</div>
</div>
</div>
)
}
export default CommodityDetail
.filter_brand {
padding: 10px 0;
.filter_brand_list {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0;
&_item {
width: 50%;
height: 60px;
list-style: none;
display: flex;
align-items: center;
justify-content: center;
.brand_img {
width: 80px;
height: 40px;
overflow: hidden;
cursor: pointer;
&>img {
height: 40px;
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import FilterBox from '../FilterBox'
import './index.less'
const Brand: React.FC = () => {
return (
<FilterBox
title="品牌"
>
<div className="filter_brand">
<ul className="filter_brand_list">
<li className="filter_brand_list_item">
<div className="brand_img">
<img src="https://img.alicdn.com/i2/2/TB1GJzSbQfb_uJjSsrbXXb6bVXa?abtest=&pos=1&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</li>
<li className="filter_brand_list_item">
<div className="brand_img">
<img src="https://img.alicdn.com/i2/2/TB1GJzSbQfb_uJjSsrbXXb6bVXa?abtest=&pos=1&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</li>
<li className="filter_brand_list_item">
<div className="brand_img">
<img src="https://img.alicdn.com/i2/2/TB1GJzSbQfb_uJjSsrbXXb6bVXa?abtest=&pos=1&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</li>
<li className="filter_brand_list_item">
<div className="brand_img">
<img src="https://img.alicdn.com/i2/2/TB1GJzSbQfb_uJjSsrbXXb6bVXa?abtest=&pos=1&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</li>
</ul>
</div>
</FilterBox>
)
}
export default Brand
.filter_category {
padding: 10px 6px 14px 0;
.sub_category_title {
position: relative;
&::before {
content: '';
position: absolute;
width: 4px;
height: 4px;
background-color: #CCCCCC;
border-radius: 50%;
top: 0;
bottom: 0;
margin: auto 0;
left: -16px
}
}
.ant-tree {
font-size: 12px;
}
.ant-tree-treenode {
height: 32px;
line-height: 32px;
display: flex;
align-items: center;
}
.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected {
background-color: #F5F5F5;
.sub_category_title {
&::before {
background-color: var(--mall_main_color);
}
}
}
.ant-tree-treenode.ant-tree-treenode-switcher-close.ant-tree-treenode-selected {
background-color: #F5F5F5;
}
.ant-tree .ant-tree-treenode {
padding: 0 0 0 8px;
width: 100%;
}
.ant-tree .ant-tree-node-content-wrapper {
line-height: 32px;
flex: 1;
}
.ant-tree-treenode.ant-tree-treenode-switcher-open.ant-tree-treenode-selected {
background-color: #F5F5F5;
}
.ant-tree-treenode {
transition: all .3s;
&:hover {
background-color: #F5F5F5;
}
}
}
\ No newline at end of file
import React from 'react'
import { Tree } from 'antd'
import FilterBox from '../FilterBox'
import './index.less'
const Category: React.FC = () => {
const treeData = [
{
title: '成品皮',
key: '0-0',
children: [
{
title: '牛皮',
key: '0-0-0',
children: [
{
title: <span className="sub_category_title">黄牛皮</span>,
key: '0-0-0-0',
},
{
title: <span className="sub_category_title" >水牛皮</span >,
key: '0-0-0-1',
},
],
},
{
title: '羊皮',
key: '0-0-1',
children: [{ title: <span style={{ color: '#1890ff' }}>sss</span>, key: '0-0-1-0' }],
},
],
},
{
title: '鞣制皮/皮胚',
key: '0-1',
children: [
{
title: '牛皮',
key: '0-1-0',
children: [
{
title: '黄牛皮',
key: '0-1-0-0',
},
{
title: '水牛皮',
key: '0-1-0-1',
},
],
},
{
title: '羊皮',
key: '0-1-1',
children: [{ title: <span style={{ color: '#1890ff' }}>sss</span>, key: '0-1-1-0' }],
},
],
},
];
const onSelect = (selectedKeys, info) => {
console.log('selected', selectedKeys, info);
};
const onCheck = (checkedKeys, info) => {
console.log('onCheck', checkedKeys, info);
};
return (
<FilterBox
title="分类"
>
<div className="filter_category">
<Tree
defaultExpandedKeys={['0-0-0', '0-0-0']}
// defaultSelectedKeys={['0-0-0', '0-0-1']}
onSelect={onSelect}
onCheck={onCheck}
treeData={treeData}
/>
</div>
</FilterBox>
)
}
export default Category
.filter_style {
padding: 15px 20px 8px 20px;
}
.ant-checkbox-group-item {
display: block;
margin-bottom: 12px;
}
.ant-checkbox-checked .ant-checkbox-inner {
background-color: var(--mall_main_color);
border-color: var(--mall_main_color);
}
\ No newline at end of file
import React from 'react'
import { Checkbox } from 'antd'
import FilterBox from '../FilterBox'
import './index.less'
const CheckboxGroup = Checkbox.Group
const CommodityType: React.FC = () => {
const styleOptions = [
{ label: '只看现价商品', value: '1' },
{ label: '只看询价商品', value: '2' },
];
const handleChange = () => {
}
return (
<FilterBox
title="商品类型"
>
<div className="filter_style">
<CheckboxGroup options={styleOptions} onChange={handleChange} />
</div>
</FilterBox>
)
}
export default CommodityType
import React from 'react'
import { CaretDownOutlined } from '@ant-design/icons'
import FilterBox from '../FilterBox'
import '../../index.less'
const CommonlyUsed: React.FC = () => {
return (
<FilterBox
title="我的常用筛选"
>
<ul className="commonly_used_list">
<li className="commonly_used_list_item">筛选组一</li>
<li className="commonly_used_list_item">筛选组二</li>
<li className="commonly_used_list_item">筛选组三</li>
</ul>
</FilterBox>
)
}
export default CommonlyUsed
import React, { useState } from 'react'
import { CaretDownOutlined } from '@ant-design/icons'
import '../../index.less'
interface FilterBoxPropsType {
title: string;
}
const FilterBox: React.FC<FilterBoxPropsType> = (props) => {
const [expand, setExpand] = useState<boolean>(true)
const { title, children } = props
return (
<div className="filter_box">
<div className="filter_box_header" onClick={() => setExpand(!expand)}>
<span>{title}</span>
<CaretDownOutlined rotate={expand ? 0 : 180} className="filter_box_header_icon" />
</div>
{
expand && (<div className="filter_box_body">
{children}
</div>)
}
</div>
)
}
export default FilterBox
.filter_price {
padding: 15px 15px 20px 15px;
.price_box {
display: flex;
font-size: 14px;
color: #333333;
align-items: center;
margin-top: 20px;
.price_box_brief {
color: #999999;
font-size: 12px;
}
.price_range {
flex: 1;
&>.split {
margin: 0 4px;
}
}
.confirm_btn {
background-color: #eeeeee;
width: 60px;
height: 24px;
line-height: 24px;
text-align: center;
cursor: pointer;
&:hover {
opacity: .8;
}
}
}
.ant-slider-track {
background-color: var(--mall_main_color);
}
.ant-slider {
&:hover {
.ant-slider-track {
background-color: var(--mall_main_color);
}
}
// background-color: var(--mall_main_color);
}
.ant-slider-handle {
width: 4px;
height: 16px;
border: none;
background-color: var(--mall_main_color);
border-radius: 0;
}
}
\ No newline at end of file
import React, { useState } from 'react'
import { Slider } from 'antd'
import FilterBox from '../FilterBox'
import './index.less'
const Price: React.FC = () => {
const [priceRange, setPriceRange] = useState<any>([0, 1000])
const handlePriceChange = (value) => {
setPriceRange(value)
}
return (
<FilterBox
title="价格"
>
<div className="filter_price">
<Slider range step={1} min={0} max={1000} value={priceRange} onChange={handlePriceChange} />
<div className="price_box">
<span className="price_box_brief">价格:</span>
<div className="price_range">
<span className="price">¥{priceRange[0]}</span>
<span className="split">-</span>
<span className="price">¥{priceRange[1]}</span>
</div>
<div className="confirm_btn">确定</div>
</div>
</div>
</FilterBox>
)
}
export default Price
.filter_style {
padding: 15px 20px 8px 20px;
}
.ant-checkbox-group-item {
display: block;
margin-bottom: 12px;
}
.ant-checkbox-checked .ant-checkbox-inner {
background-color: var(--mall_main_color);
border-color: var(--mall_main_color);
}
\ No newline at end of file
import React from 'react'
import { Checkbox } from 'antd'
import FilterBox from '../FilterBox'
import './index.less'
const CheckboxGroup = Checkbox.Group
const Style: React.FC = () => {
const styleOptions = [
{ label: '荔枝纹', value: '1' },
{ label: '网纹', value: '2' },
{ label: '自然摔纹', value: '3' },
];
const handleChange = () => {
}
return (
<FilterBox
title="风格"
>
<div className="filter_style">
<CheckboxGroup options={styleOptions} onChange={handleChange} />
</div>
</FilterBox>
)
}
export default Style
.filter_usearea {
padding-top: 15px;
.filter_usearea_list {
display: flex;
flex-wrap: wrap;
&_item {
// position: relative;
width: 25%;
text-align: center;
margin-bottom: 10px;
font-size: 12px;
color: #333333;
&>.text {
cursor: pointer;
}
&.active {
&>.text {
padding: 1px 3px;
background-color: var(--mall_main_color);
color: #ffffff;
}
}
.more_panel {
// position: relative;
margin-top: 5px;
.sub_area_list_hidden {
position: relative;
display: flex;
opacity: 0;
left: -1240px;
width: 240px;
flex-wrap: wrap;
padding: 10px 5px 0 5px;
}
.sub_area_list_item {
padding: 0 10px;
margin-bottom: 10px;
cursor: pointer;
&.active {
color: var(--mall_main_color);
}
}
.sub_area_list {
position: absolute;
width: 240px;
padding: 10px 5px 0 5px;
left: 0;
display: flex;
flex-wrap: wrap;
background-color: #F5F5F5;
}
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import FilterBox from '../FilterBox'
import cx from 'classnames'
import './index.less'
const UseArea: React.FC = () => {
const [selectCity, setSelectCity] = useState<string[]>([])
const mockData = [
{
label: '北京',
value: 'bj',
children: [
{
label: '东城区',
value: 'dcq',
},
]
},
{
label: '天津',
value: 'tj',
},
{
label: '江苏',
value: 'js',
children: [
{
label: '南京',
value: 'nj',
},
{
label: '苏州',
value: 'szj',
},
{
label: '无锡',
value: 'wx',
},
{
label: '常州',
value: 'cz',
},
{
label: '镇江',
value: 'zj',
},
{
label: '扬州',
value: 'yz',
},
{
label: '盐城',
value: 'yc',
},
]
},
{
label: '上海',
value: 'sh',
},
{
label: '重庆',
value: 'chq',
},
{
label: '河北',
value: 'hb',
children: [
{
label: '石家庄市',
value: 'sjz',
},
]
},
]
const handleSelect = (key: string, type: number) => {
if (type === 1) {
setSelectCity([key])
} else {
setSelectCity([selectCity[0], key])
}
}
return (
<FilterBox
title="适用地区"
>
<div className="filter_usearea">
<div className="filter_usearea_list">
{
mockData.map(item => (
<div key={item.value} className={cx("filter_usearea_list_item", selectCity.includes(item.value) ? "active" : '')}>
<span className="text" onClick={() => handleSelect(item.value, 1)}>{item.label}</span>
{
(selectCity.includes(item.value) && !!item.children) && (
<div className="more_panel">
<div className="sub_area_list">
{
item.children.map(childItem => (
<div onClick={() => handleSelect(childItem.value, 2)} className={cx("sub_area_list_item", selectCity.includes(childItem.value) ? 'active' : '')}>
{childItem.label}
</div>
))
}
</div>
<div className="sub_area_list_hidden">
{
item.children && item.children.map(childItem => (
<div className="sub_area_list_item">
{childItem.label}
</div>
))
}
</div>
</div>
)
}
</div>
))
}
</div>
</div>
</FilterBox>
)
}
export default UseArea
.filter {
width: 240px;
margin-right: 20px;
.filter_box {
.filter_box_header {
position: relative;
height: 40px;
line-height: 40px;
padding-left: 15px;
background-color: #F5F5F5;
cursor: pointer;
color: #3A3A3A;
font-size: 14px;
font-weight: 500;
&_icon {
position: absolute;
display: block;
top: 0;
bottom: 0;
right: 22px;
width: 12px;
height: 12px;
margin: auto 0;
color: #CCCCCC;
font-size: 12px;
}
}
.filter_box_body {
position: relative;
}
}
.commonly_used_list {
display: flex;
padding: 5px 0 10px 0;
flex-wrap: wrap;
margin: 0;
&_item {
list-style: none;
padding: 10px 15px;
font-size: 12px;
}
}
}
\ No newline at end of file
import React from 'react'
import CommonlyUsed from './components/CommonlyUsed'
import Category from './components/Category'
import Style from './components/Style'
import Brand from './components/Brand'
import Price from './components/Price'
import UseArea from './components/UseArea'
import CommodityType from './components/CommodityType'
import './index.less'
const Filter: React.FC = () => {
return (
<div className="filter">
<CommonlyUsed />
<Category />
<Style />
<Brand />
<Price />
<UseArea />
<CommodityType />
</div>
)
}
export default Filter
.find_more {
position: relative;
padding-top: 20px;
margin-bottom: 20px;
.find_more_container {
width: 1200px;
margin: 0 auto;
.find_more_header {
font-size: 20px;
color: #333333;
padding: 20px 0;
}
.find_more_main {
display: flex;
.find_more_title {
height: 60px;
line-height: 60px;
padding-left: 20px;
display: flex;
&>label {
color: #E44E46;
margin-right: 10px;
font-size: 16px;
font-weight: 500;
&.blue {
color: #6386D1;
}
}
&>span {
color: #999999;
font-size: 12px;
}
.find_more_title_page {
display: flex;
padding: 0 20px;
align-items: center;
margin-left: auto;
&>.page_item {
width: 24px;
height: 24px;
background-color: #F5F5F5;
line-height: 24px;
font-size: 14px;
color: #979797;
text-align: center;
cursor: pointer;
&:hover {
opacity: .8;
}
&.prev {
margin-right: 16px;
}
}
}
}
.popular_shops {
width: 315px;
background: #ffffff;
.popular_shops_list {
padding: 20px 25px;
padding-bottom: 12px;
&_item {
display: flex;
margin-bottom: 20px;
align-items: center;
.popular_shops_rank {
width: 22px;
height: 32px;
line-height: 32px;
font-size: 14px;
color: #666666;
font-weight: 500;
margin-right: 20px;
}
.popular_shops_logo {
width: 36px;
height: 36px;
overflow: hidden;
margin-right: 10px;
&>img {
width: 100%;
height: 100%;
}
}
.popular_shops_name {
color: #333333;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&>a {
color: #333333;
}
}
}
}
}
.popular_buy_dynamic {
flex: 1;
margin: 0 20px;
background: #ffffff;
.popular_buy_dynamic_list {
display: flex;
flex-wrap: wrap;
&_item {
width: 50%;
padding: 20px;
&_header {
display: flex;
align-items: center;
&>span {
flex: 1;
display: block;
color: #333333;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
.status_tag {
height: 20px;
padding: 0 6px;
line-height: 20px;
text-align: center;
color: #ffffff;
font-size: 12px;
background-color: #5988D5;
&.success {
color: #666666;
background-color: #EEEEEE;
}
}
}
&_content {
display: flex;
margin-top: 24px;
.content_text {
flex: 1;
color: #333333;
font-size: 14px;
line-height: 14px;
}
.content_time {
font-size: 12px;
color: #999999;
}
}
}
}
}
.new_trade {
width: 285px;
background: #ffffff;
.new_trade_list {
&_item {
padding: 12px 20px;
&_header {
display: flex;
align-items: center;
&>span {
flex: 1;
display: block;
color: #333333;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
}
.price {
font-size: 16px;
color: #D32F2F;
font-weight: 500;
}
}
&_content {
display: flex;
margin-top: 12px;
font-size: 12px;
color: #999999;
.content_text {
flex: 1;
}
}
}
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import cx from 'classnames'
import './index.less'
const FindMore: React.FC = () => {
const buy_dynamic_list = [
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 0,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
{
title: '黑色头层牛皮自然摔纹',
state: 1,
content: '2000平方英尺',
date: '09/09 09:00'
},
]
return (
<div className="find_more" id="find_more">
<div className="find_more_container">
<div className="find_more_header">发现更多</div>
<div className="find_more_main">
<div className="popular_shops">
<div className="find_more_title">
<label>人气店铺</label>
<span>排名每天凌晨更新</span>
</div>
<div className="popular_shops_list">
<div className="popular_shops_list_item">
<div className="popular_shops_rank">01</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name"> <a href="/">无锡市群明钢业有限公司</a></div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">02</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">03</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">04</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
<div className="popular_shops_list_item">
<div className="popular_shops_rank">05</div>
<div className="popular_shops_logo">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3381279230,433852972&fm=26&gp=0.jpg" />
</div>
<div className="popular_shops_name">无锡市群明钢业有限公司</div>
</div>
</div>
</div>
<div className="popular_buy_dynamic">
<div className="find_more_title">
<label className="blue">求购动态</label>
<span>买家求购,卖家快速报价</span>
<div className="find_more_title_page">
<div className="page_item prev"><LeftOutlined /></div>
<div className="page_item next"><RightOutlined /></div>
</div>
</div>
<div className="popular_buy_dynamic_list">
{
buy_dynamic_list.map((item, index) => (
<div className="popular_buy_dynamic_list_item" key={`popular_buy_dynamic_list_item_${index}`}>
<div className="popular_buy_dynamic_list_item_header">
<span>{item.title}</span>
<div className={cx("status_tag", item.state === 1 ? 'success' : '')}>{item.state === 1 ? '已完成' : '比价中'}</div>
</div>
<div className="popular_buy_dynamic_list_item_content">
<span className="content_text">{item.content}</span>
<span className="content_time">{item.date}</span>
</div>
</div>
))
}
</div>
</div>
<div className="new_trade">
<div className="find_more_title">
<label>最新成交</label>
</div>
<div className="new_trade_list">
{
buy_dynamic_list.map((item, index) => index < 4 && (
<div className="new_trade_list_item" key={`new_trade_list_item_${index}`}>
<div className="new_trade_list_item_header">
<span>{item.title}</span>
<div className="price">2000</div>
</div>
<div className="new_trade_list_item_content">
<span className="content_text">{item.date}</span>
<span className="content_time">平方英尺</span>
</div>
</div>
))
}
</div>
</div>
</div>
</div>
</div>
)
}
export default FindMore
.anchor_wrap {
position: relative;
width: 1200px;
margin: 0 auto;
z-index: 9;
.anchor {
position: absolute;
top: 20px;
width: 88px;
left: -128px;
margin-left: 0;
padding-left: 0;
.ant-anchor {
padding-left: 0;
padding-top: 8px;
.ant-anchor-ink {
display: none;
}
.ant-anchor-link {
padding: 0;
height: 32px;
line-height: 32px;
padding-left: 11px;
font-size: 12px;
&.ant-anchor-link-active {
background-color: var(--mall_main_color);
color: #ffffff;
&>a {
color: #ffffff;
}
}
}
}
.ant-back-top {
position: relative;
right: 0;
bottom: 0;
width: 88px;
height: 32px;
line-height: 32px;
font-size: 12px;
padding-left: 12px;
.text {
margin-left: 8px;
}
}
.qrcode {
width: 100%;
font-size: 12px;
text-align: center;
background-color: #f5f5f5;
.qrcode_img {
height: 88px;
background-color: #ffffff;
&>img {
width: 100%;
height: 100%;
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import { ToTopOutlined } from '@ant-design/icons'
import { Anchor, BackTop } from 'antd'
import qrcodeImg from '@/assets/imgs/erweima.png'
import './index.less'
interface FloorAnchorPropsType {
anchorList: any;
type: string;
}
const FloorAnchor: React.FC<FloorAnchorPropsType> = (props) => {
const { anchorList = [], type } = props
return (
<div className="anchor_wrap">
<Anchor className="anchor" offsetTop={120} >
{
anchorList.map(item => (
<Anchor.Link key={item.id} href={`#floorline_${item.id}`} title={item.title} />
))
}
{
type === 'mall' && <Anchor.Link href={`#find_more`} title="发现更多" />
}
<BackTop>
<ToTopOutlined />
<span className="text">顶部</span>
</BackTop>
{
type === 'mall' && (
<div className="qrcode">
<div className="qrcode_img">
<img src={qrcodeImg} />
</div>
<div>扫码下载APP</div>
</div>
)
}
</Anchor>
</div>
)
}
export default FloorAnchor
......@@ -31,7 +31,7 @@ export default class Brand extends React.Component<BrandProps, {}> {
</div>
<div className="brand_list_item">
<div className="brand_img_box">
<img src="https:////img.alicdn.com/i2/2/TB1pwpNhfBNTKJjy1zdXXaScpXa?abtest=&pos=13&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
<img src="https://img.alicdn.com/i2/2/TB1pwpNhfBNTKJjy1zdXXaScpXa?abtest=&pos=13&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</div>
<div className="brand_list_item">
......@@ -41,7 +41,7 @@ export default class Brand extends React.Component<BrandProps, {}> {
</div>
<div className="brand_list_item">
<div className="brand_img_box">
<img src="https:////img.alicdn.com/i2/2/TB1pwpNhfBNTKJjy1zdXXaScpXa?abtest=&pos=13&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
<img src="https://img.alicdn.com/i2/2/TB1pwpNhfBNTKJjy1zdXXaScpXa?abtest=&pos=13&abbucket=&acm=09042.1003.1.1200415&scm=1007.13029.131809.100200300000000_200x200q100.jpg_.webp" />
</div>
</div>
<div className="brand_list_item">
......
......@@ -33,7 +33,9 @@ export default class Goods extends React.Component<GoodsProps, {}> {
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="goods_name">产地大厂精选尖货</div>
<div className="goods_price"><span></span>79.00</div>
<div className="goods_price">
<span></span>79.00
</div>
</Link>
</div>
......
......@@ -157,6 +157,7 @@
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
padding: 0 15px;
margin-top: 15px;
}
......@@ -164,8 +165,10 @@
text-align: center;
color: var(--mall_main_color);
margin-top: 16px;
padding: 0 15px;
line-height: 16px;
&>span {
font-size: 12px;
......
......@@ -17,6 +17,7 @@ import './index.less'
interface FloorLineProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
prefixCls?: string;
title?: React.ReactNode | string;
anchor?: string;
}
interface FloorLineInterface extends FloorLineProps {
......@@ -33,12 +34,12 @@ interface FloorLineInterface extends FloorLineProps {
const FloorLine: FloorLineInterface & React.FC<FloorLineInterface> = (props) => {
const { getPrefixCls } = React.useContext(ConfigContext);
const { children, title, className, ...others } = props
const { children, title, className, anchor, ...others } = props
const prefixCls = getPrefixCls('floor_line', props.prefixCls);
const classString = classNames(prefixCls, className);
return (
<div className={classString} {...others}>
<div className={classString} id={anchor} {...others}>
<div className="floor_line_container">
<div className="floor_line_name">
<span className="floor_line_name_text">{title}</span>
......
.footer {
width: 100%;
background-color: #FAFAFA;
margin-top: 52px;
&_container {
width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 88px 50px 88px;
.footer_nav_item {
padding: 0;
margin: 0;
padding-top: 52px;
&>li {
list-style: none;
font-size: 12px;
color: #999999;
margin-bottom: 10px;
&>a {
color: #999999;
}
&.title {
font-size: 14px;
color: #666666;
margin-bottom: 15px;
}
}
}
}
.copyright {
background-color: #f5f5f5;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 12px;
color: #999999;
}
}
\ No newline at end of file
import React from 'react'
import './index.less'
const Footer: React.FC = () => {
const footer_nav_list = [
{
title: '会员服务',
children: [
{
path: '/user/register',
title: '会员注册'
},
{
path: '/user/login',
title: '登录'
},
{
path: '/',
title: '会员认证'
},
{
path: '/',
title: '会员服务'
},
]
},
{
title: '采购&供应',
children: [
{
path: '/',
title: '发布供应信息'
},
{
path: '/',
title: '发布求购信息'
},
{
path: '/',
title: '购买商品'
},
{
path: '/',
title: '询价报价'
},
]
},
{
title: '账户&安全',
children: [
{
path: '/',
title: '账户查询'
},
{
path: '/',
title: '账户管理'
},
{
path: '/',
title: '安全中心'
},
{
path: '/',
title: '密码服务'
},
]
},
{
title: '信用评价',
children: [
{
path: '/',
title: '发布评价'
},
{
path: '/',
title: '查看评价'
},
{
path: '/',
title: '投诉举报'
},
{
path: '/',
title: '评价规则'
},
]
},
{
title: '关于我们',
children: [
{
path: '/',
title: '平台介绍'
},
{
path: '/',
title: '联系我们'
},
{
path: '/',
title: '服务条款'
},
{
path: '/',
title: '免责声明'
},
]
}
]
return (
<div className="footer">
<div className="footer_container">
{
footer_nav_list.map((item, index) => (
<ul className="footer_nav_item" key={`footer_nav_item_${index}`}>
<li className="title">{item.title}</li>
{
item.children.map((item, index) => (
<li key={`footer_nav_item_${index}`}><a href={item.path}>{item.title}</a></li>
))
}
</ul>
))
}
</div>
<div className="copyright">
Copy Right©广州市数商云网络科技有限公司 粤ICP备13044797号-5
</div>
</div>
)
}
export default Footer
\ No newline at end of file
......@@ -23,4 +23,103 @@
}
}
}
.information_list {
display: flex;
&_item {
width: 50%;
padding: 20px 0 20px 20px;
&:not(:last-child) {
.information_list_item_body {
border-right: 1px solid #f5f5f5;
}
}
&_body {
padding-right: 20px;
.information_recommand {
padding: 10px 0;
display: flex;
&_img {
width: 220px;
height: 146px;
overflow: hidden;
&>img {
height: auto;
width: 100%;
display: block;
margin: 0 auto;
}
}
&_content {
padding-left: 15px;
flex: 1;
&_title {
font-size: 14px;
color: #333333;
margin-top: 10px;
}
&_subtitle {
color: #999999;
font-size: 12px;
margin-top: 5px;
}
&_date {
color: #999999;
font-size: 12px;
margin-top: 10px;
}
&_content {
color: #999999;
font-size: 12px;
margin-top: 10px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
word-wrap: break-word;
word-break: break-all;
}
}
}
.news_list {
margin-top: 10px;
&_item {
display: flex;
margin-bottom: 10px;
&_title {
color: #3A3A3A;
font-size: 14px;
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&_date {
font-size: 12px;
color: #999999;
}
}
}
}
}
}
}
\ No newline at end of file
import React from 'react'
import { Link } from 'umi'
import './index.less'
const Information: React.FC = () => {
......@@ -10,8 +11,85 @@ const Information: React.FC = () => {
<span>行情资讯</span>
<label>今日热点 | 行业头条 | 专题报道 | 政策法规 ...</label>
</div>
</div>
<div className="information_list">
<div className="information_list_item">
<div className="information_list_item_body">
<Link to="/">
<div className="information_recommand">
<div className="information_recommand_img">
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="information_recommand_content">
<div className="information_recommand_content_title">温州国际皮革展开幕预登记倒计时!</div>
<div className="information_recommand_content_subtitle">快捷入场参观,免费领取会刊</div>
<div className="information_recommand_content_date">2020-08-25</div>
<div className="information_recommand_content_content">正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正</div>
</div>
</div>
</Link>
<div className="news_list">
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
</div>
</div>
</div>
<div className="information_list_item">
<div className="information_list_item_body">
<Link to="/">
<div className="information_recommand">
<div className="information_recommand_img">
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="information_recommand_content">
<div className="information_recommand_content_title">温州国际皮革展开幕预登记倒计时!</div>
<div className="information_recommand_content_subtitle">快捷入场参观,免费领取会刊</div>
<div className="information_recommand_content_date">2020-08-25</div>
<div className="information_recommand_content_content">正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正</div>
</div>
</div>
</Link>
<div className="news_list">
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
<Link to="/">
<div className="news_list_item">
<div className="news_list_item_title">天生与福气有缘,注定会桃花自来,财运横飞的四大生肖</div>
<div className="news_list_item_date">2020-08-25</div>
</div>
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
......
import React from 'react'
import classNames from 'classnames'
import { CaretRightOutlined } from '@ant-design/icons'
import { ConfigConsumer } from '../Generator'
interface CategoryProps {
className?: string;
prefixCls?: string;
}
export default class Category extends React.Component<CategoryProps, {}> {
renderComponent = ({ getPrefixCls }: any) => {
const { children, className, ...others } = this.props
const prefixCls = getPrefixCls('shop-floor-line-category', this.props.prefixCls);
const classString = classNames(prefixCls, className);
const mockList = [
{
id: 1,
name: '文件柜'
},
{
id: 2,
name: '岩板餐桌'
},
{
id: 3,
name: '五金'
},
{
id: 4,
name: '五金'
},
]
return (
<section className={classString} {...others}>
<img className="floor-line-category-banner" src="https://img.alicdn.com/tps/i4/TB1MesKcWmWQ1JjSZPhwu0CJFXa.png" />
<div className="recommend_category_list">
{
mockList.map(item => (
<div className="recommend_category_list_item" key={item.id}>
<a href="">
<div className="recommend_category_list_item_body">
<span className="text">{item.name}</span>
<CaretRightOutlined className="icon" />
</div>
</a>
</div>
))
}
</div>
</section>
)
}
render() {
return <ConfigConsumer>{this.renderComponent}</ConfigConsumer>
}
}
\ No newline at end of file
import React from 'react'
import classNames from 'classnames'
import { Link } from 'umi'
import cx from 'classnames'
import { ConfigConsumer } from '../Generator'
interface GoodsProps {
className?: string;
prefixCls?: string;
}
export default class Goods extends React.Component<GoodsProps, {}> {
renderShowCase = ({ getPrefixCls }: any) => {
const { children, className, ...others } = this.props
const prefixCls = getPrefixCls('shop-floor-line-goods', this.props.prefixCls);
const classString = classNames(prefixCls, className);
let dataList = []
for (let i = 0; i < 10; i++) {
dataList.push(i)
}
return (
<section className={classString} {...others}>
<div className="goods_list">
{
dataList.map((item, index) => index === 0 ? (
<div key={item} className="goods_list_item empty">
</div>
) : (
<div key={item} className="goods_list_item">
<Link to="/">
<div className="goods_img">
<img src="https://img.alicdn.com/bao/uploaded/i1/691602756/O1CN013mdkHl1WEI92iLR75_!!691602756.jpg_400x400q60.jpg" />
</div>
<div className="goods_name">产地大厂精选尖货</div>
<div className="goods_price">
<span></span>79.00
<div className="count">已售3,230</div>
</div>
</Link>
</div>
))
}
</div>
</section>
)
}
render() {
return <ConfigConsumer>{this.renderShowCase}</ConfigConsumer>
}
}
\ No newline at end of file
.lingxi-shop_floor_line {
position: relative;
.floor_line_container {
padding-top: 42px;
padding-bottom: 40px;
border-bottom: 1px solid #E5E5E5;
width: 1200px;
margin: 0 auto;
.floor_line_body {
position: relative;
}
.floor_line_name {
line-height: 20px;
margin-bottom: 22px;
.floor_line_name_text {
font-size: 20px;
font-weight: bold;
color: #333333;
}
.floor_line_more {
float: right;
color: #666666;
font-size: 14px;
}
}
}
}
// 品类样式
.lingxi-shop-floor-line-category {
position: absolute;
top: 0;
left: 0;
width: 240px;
height: 300px;
overflow: hidden;
z-index: 2;
.floor-line-category-banner {
width: 100%;
height: auto;
}
.recommend_category_list {
position: absolute;
display: flex;
flex-wrap: wrap;
width: 200px;
bottom: 20px;
left: 20px;
z-index: 5;
&_item {
width: 100px;
background: rgba(0, 0, 0, 0.65);
opacity: 0.9;
border: 1px solid rgba(255, 255, 255, 0.2);
&:hover {
background: rgba(0, 0, 0, 0.55);
}
.recommend_category_list_item_body {
display: flex;
align-items: center;
height: 32px;
justify-content: center;
color: #ffffff;
&>.text {
font-size: 12px;
width: 56px;
display: block;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&>.icon {
color: #999999;
font-size: 10px;
margin-left: 12px;
}
}
}
a {
color: #333333;
}
}
}
// 商品列表样式
.lingxi-shop-floor-line-goods {
position: relative;
width: 1200px;
background: #ffffff;
z-index: 1;
.goods_list {
display: flex;
flex-wrap: wrap;
&_item {
width: 240px;
height: 300px;
padding-top: 20px;
&.empty {
background: #f5f5f5;
}
a {
outline: none;
}
.goods_img {
width: 200px;
height: 200px;
overflow: hidden;
margin: 0 auto;
&>img {
height: 100%;
display: block;
margin: 0 auto;
}
}
.goods_name {
font-size: 14px;
color: #333333;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 14px;
padding: 0 20px;
margin-top: 15px;
}
.goods_price {
padding: 0 20px;
color: var(--mall_main_color);
margin-top: 16px;
line-height: 16px;
display: flex;
align-items: center;
&>.count {
margin-left: auto;
font-size: 12px;
color: #999999;
}
&>span {
font-size: 12px;
}
}
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment