Commit 87d2f00a authored by GuanHua's avatar GuanHua

feat: 新增商品浏览记录列表

parent e2319326
......@@ -18,7 +18,6 @@ import IconFont from '@/utils/iconfont'
import { GetSearchShopStoreGetCommodityDetailResponse, GetSearchShopChannelGetCommodityDetailResponse } from '@/services/SearchApi'
import { getAuth } from '@/utils/auth'
import { numFormat, priceFormat } from '@/utils/numberFomat'
import jinhuodanIcon from '@/assets/imgs/jinhuodan.png'
import styles from './index.less'
import { GlobalConfig } from '@/global/config'
import ErrorResult from './error'
......@@ -81,7 +80,9 @@ const CommodityDetail = (props) => {
const { query: { id, type } } = props.location
const { shopInfo = {}, shopId, layoutType, memberId, shopUrlParam } = props
const OrderStore = useLocalStore(() => store.OrderStore)
const BrowerHistoryStore = useLocalStore(() => store.BrowerHistoryStore)
const { updateOrderInfo } = OrderStore
const { updateCommodityBrowerHistory } = BrowerHistoryStore
const [addSuccessVisible, setAddSuccessVisible] = useState<boolean>(false)
const [attributeList, setAttributeList] = useState([])
const [commodityDetail, setCommodityDetail] = useState<GetSearchShopStoreGetCommodityDetailResponse & GetSearchShopChannelGetCommodityDetailResponse>()
......@@ -188,7 +189,7 @@ const CommodityDetail = (props) => {
commodityId: id
}
let headers = {}
console.log(layoutType, "layoutType")
switch (layoutType) {
case LAYOUT_TYPE.channel:
if(type === "3") {
......@@ -228,6 +229,19 @@ const CommodityDetail = (props) => {
setCommodityDetail(res.data)
initAttributeAndValueList(res.data)
getPayWayListByMemberId(res.data?.memberId, res.data?.memberRoleId)
updateCommodityBrowerHistory({
id: res.data.id,
/** 商品名称 */
name: res.data.name,
/** 商品价格 */
price: res.data.min,
/** 商品价格类型 */
priceType: res.data.priceType,
/** 商品图片 */
mainPic: res.data.mainPic,
storeId: res.data.storeId,
memberId: res.data.memberId,
})
if(!type) {
uploadStoreId(getLayoutType(layoutType, Number(res.data.priceType)))
}
......
import React from 'react'
import cx from 'classnames'
import './index.less'
import { CloseOutlined } from '@ant-design/icons'
import ImageBox from '@/components/ImageBox'
import { LAYOUT_TYPE } from '@/constants'
import { BrowserHistoryStoreType } from '@/store/browerHistory/types'
import { inject, observer } from 'mobx-react'
import { GlobalConfig } from '@/global/config'
import { numFormat } from '@/utils/numberFomat'
import styles from './index.less'
interface FootPrintPropsType {
visible: boolean;
BrowerHistoryStore?: BrowserHistoryStoreType,
onClose: Function,
type: LAYOUT_TYPE,
shopUrlParam?: string
}
const FootPrint: React.FC<FootPrintPropsType> = (props) => {
const { visible = false } = props
const { visible = false, onClose, BrowerHistoryStore, type } = props
const { commodityListHistory } = BrowerHistoryStore
const renderPrice = (item) => {
switch (item.priceType) {
case 1:
return (
<div className={styles.commodityPrice}>
<span></span>
<span>{item.price}</span>
</div>
)
case 2:
return (
<div className={styles.inquiry_price}>
<label>在线询价</label>
</div>
)
case 3:
return (
<div className={styles.goods_price}>
{numFormat(item.price)}积分
</div>
)
default:
return null
}
}
const getCommodityDetailLink = (item) => {
let link = ""
switch (type) {
case LAYOUT_TYPE.channel:
link = `${GlobalConfig.channelRootRoute}/commodity/detail?id=${item.id}&type=${item.priceType}&channelId=${btoa(JSON.stringify({ shopId: item.storeId, memberId: item.memberId }))}`
break
case LAYOUT_TYPE.ichannel:
link = `${GlobalConfig.ichannelRootRoute}/commodity/detail?id=${item.id}&type=${item.priceType}&channelId=${btoa(JSON.stringify({ shopId: item.storeId, memberId: item.memberId }))}`
break
default:
link = `/shop/commodity/detail?id=${item.id}&type=${item.priceType}&shopId=${btoa(JSON.stringify({ shopId: item.storeId, memberId: item.memberId }))}`
break
}
return link
}
return (
<div className={cx("footprint", visible ? 'show' : 'hide')}>
<div className="footprint_title">浏览记录</div>
<div className={cx(styles.footprint, visible ? styles.show : styles.hide)}>
<div className={styles.footprint_title}>
<span>浏览记录</span>
<CloseOutlined onClick={() => onClose()} className={styles.footprint_title_close} />
</div>
<div className={styles.commodityList}>
{
commodityListHistory && commodityListHistory.map((commodityItem) => (
<div className={styles.commodityItem} key={`commodityItem${commodityItem.id}`}>
<div className={styles.commodityItemBody}>
<a href={getCommodityDetailLink(commodityItem)} target="_blank" rel="noreferrer">
<ImageBox width={105} height={105} imgUrl={commodityItem.mainPic} />
<div className={styles.commodityName}>{commodityItem.name}</div>
{renderPrice(commodityItem)}
</a>
</div>
</div>
))
}
</div>
</div>
)
}
export default FootPrint
export default inject("BrowerHistoryStore")(observer(FootPrint))
......@@ -25,14 +25,18 @@
width: 40px;
height: 40px;
background-color: #262626;
margin-bottom: 5px;
color: #FFF;
display: flex;
margin-bottom: 2px;
align-items: center;
justify-content: center;
font-size: 16px;
transition: all .3s;
// &:not(:last-child) {
// border-bottom: 1px dashed rgba(255, 255, 255, .8);
// }
&>a {
display: block;
color: #FFF;
......@@ -40,38 +44,92 @@
&:hover {
cursor: pointer;
// background-color: var(--mall_main_color);
background-color: #D32F2F;
background-color: var(--mall_main_color);
}
}
}
.footprint {
position: relative;
width: 240px;
height: 100%;
background-color: #FFF;
transition: all .3s;
&_title {
height: 40px;
line-height: 40px;
padding-left: 10px;
}
}
.commodityList {
display: flex;
flex-wrap: wrap;
padding: 0 5px 50px 0;
overflow-y: auto;
height: 100vh;
.commodityItem {
width: 50%;
.commodityItemBody {
padding: 5px;
.commodityName {
font-size: 12px;
color: #303133;
border-bottom: 1px solid #F4F5F7;
color: #333333;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
&.show {
width: 240px;
opacity: 1;
.commodityPrice {
font-size: 14px;
color: #D32F2F;
}
}
}
}
&.hide {
width: 0;
opacity: 0;
}
.inquiry_price {
color: #FFF;
background-color: var(--mall_main_color);
font-size: 12px;
padding: 2px 6px;
display: inline-block;
}
.goods_price {
color: #EA8000;
line-height: 16px;
display: flex;
font-size: 12px;
align-items: center;
}
.footprint {
position: relative;
width: 240px;
height: 100%;
background-color: #FFF;
transition: all .3s;
&_title {
display: flex;
align-items: center;
height: 40px;
padding-left: 10px;
font-size: 12px;
color: #303133;
border-bottom: 1px solid #F4F5F7;
&_close {
margin-left: auto;
color: #999999;
cursor: pointer;
margin-right: 8px;
}
}
}
\ No newline at end of file
&.show {
width: 240px;
opacity: 1;
}
&.hide {
width: 0;
opacity: 0;
}
}
......@@ -55,14 +55,14 @@ const SideNav: React.FC<SideNavPropsType> = (props) => {
<div className="side_nav_list_item" onClick={() => history.push('/memberCenter/systemSetting/message')}>
<IconFont type="icon-xiaoxi" />
</div>
<div className="side_nav_list_item" onClick={() => showToggleFootPrint()}>
<IconFont type="icon-jilu" />
</div>
<div className="side_nav_list_item">
<IconFont type="icon-erweima1" />
</div>
{/* <div className="side_nav_list_item" onClick={() => showToggleFootPrint()}>
<MyIcon type="icon-jilu" />
</div> */}
</div>
<FootPrint visible={footPrintVisible} />
<FootPrint visible={footPrintVisible} onClose={() => showToggleFootPrint()} {...props} />
</div>
</div>
)
......
import { action, observable } from 'mobx'
import { CommodityItemType } from './types'
const localCommodityListHistory = localStorage.getItem("commodityListHistory")
class BrowserHistoryStore {
@observable public commodityListHistory: CommodityItemType[] = localCommodityListHistory ? JSON.parse(localCommodityListHistory) : []; // 浏览商品记录列表
/**
* 更新浏览商品记录
*/
@action.bound
public updateCommodityBrowerHistory(commodityItem: CommodityItemType) {
if(this.commodityListHistory.length === 0 || this.commodityListHistory.every((item) => item.id !== commodityItem.id)) {
this.commodityListHistory = [commodityItem, ...this.commodityListHistory]
this.commodityListHistory = this.commodityListHistory.splice(0, 50)
localStorage.setItem("commodityListHistory", JSON.stringify(this.commodityListHistory))
}
}
}
export default BrowserHistoryStore
export interface CommodityItemType {
/** 商品id */
id: number,
/** 商品名称 */
name: string,
/** 商品价格 */
price: number,
/** 商品价格类型 */
priceType: number,
/** 商品图片 */
mainPic: string,
storeId: number,
memberId: number,
}
export interface BrowserHistoryStoreType {
commodityListHistory: CommodityItemType[],
updateCommodityBrowerHistory: Function,
}
import { action, computed, observable, runInAction } from 'mobx'
import { LAYOUT_TYPE } from '@/constants'
import { PublicApi } from '@/services/api'
class CategoryStore {
@observable public categoryList: any = []; // 品类列表
@observable public enterpriseCategoryList: any = []
@observable public storeCategoryList: any = []
@observable public categoryType: LAYOUT_TYPE | null = null
/**
* 企业商城商品分类列表
*/
@action.bound
public async fetchCategoryList(getCategoryFn, params, type, options?) {
if (this.categoryType !== type) {
this.categoryType = type
let res = await getCategoryFn(params, options || {})
runInAction(() => {
this.categoryList = res.data || []
})
}
}
/**
* 企业商城商品分类列表
*/
@action.bound
public async fetchEnterpriseCategoryList() {
let res = await PublicApi.getSearchShopEnterpriseGetCategoryTree()
runInAction(() => {
this.enterpriseCategoryList = res.data || []
})
}
/**
* 店铺商城商品分类列表
*/
@action.bound
public async fetchStoreCategoryList(param) {
let res = await PublicApi.getSearchShopStoreGetCustomerCategoryTree(param)
runInAction(() => {
this.storeCategoryList = res.data || []
})
}
}
export default CategoryStore
import { action, observable, runInAction } from 'mobx'
import { LAYOUT_TYPE } from '@/constants'
import { PublicApi } from '@/services/api'
class CategoryStore {
@observable public categoryList: any = []; // 品类列表
@observable public enterpriseCategoryList: any = []
@observable public storeCategoryList: any = []
@observable public categoryType: LAYOUT_TYPE | null = null
/**
* 企业商城商品分类列表
*/
@action.bound
public async fetchCategoryList(getCategoryFn, params, type, options?) {
if (this.categoryType !== type) {
this.categoryType = type
const res = await getCategoryFn(params, options || {})
runInAction(() => {
this.categoryList = res.data || []
})
}
}
/**
* 企业商城商品分类列表
*/
@action.bound
public async fetchEnterpriseCategoryList() {
const res = await PublicApi.getSearchShopEnterpriseGetCategoryTree()
runInAction(() => {
this.enterpriseCategoryList = res.data || []
})
}
/**
* 店铺商城商品分类列表
*/
@action.bound
public async fetchStoreCategoryList(param) {
const res = await PublicApi.getSearchShopStoreGetCustomerCategoryTree(param)
runInAction(() => {
this.storeCategoryList = res.data || []
})
}
}
export default CategoryStore
import React from 'react';
import { Provider } from 'mobx-react'
import UserStore from './user'
import ThemeStore from './theme'
import ProductStroe from './product'
import OrderStore from './order'
import ChannelProudctStore from './channelProduct'
import SiteStore from './site'
import CategoryStore from './category'
import FilterStore from './filter'
import MemberStore from './member'
import EvaluationStore from './evaluation';
import { ILoginModule } from '@/module/userModule';
import { IProductModule } from '@/module/productModule'
import { IChannelProductModule } from '@/module/channelProductModule'
import { IMemberModule } from '@/module/memberModule';
import { IEvaluationModule } from '@/module/evaluationModule';
// import { ProductContext } from '@/pages/commodity/products/addProducts';
/**
*
* mobx使用说明
* @observable 只有被这个装饰后才能监听数据变化
* @computed 是根据@observable的数据计算属性
* @action 只能是同步处理数据,不能异步
* @action.bound 可以保证装饰的函数内部this永远指向当前store
* runInAction 是在action中做异步处理时需要调用的
*
* 官方文档:https://mobx.js.org/
* 中文文档:https://cn.mobx.js.org/
*
*
*/
export interface IStore {
UserStore: ILoginModule;
ProductStore: IProductModule;
ChannelProudctStore: IChannelProductModule;
MemberModuleStore: IMemberModule;
EvaluationModule: IEvaluationModule;
}
export const store = {
UserStore: new UserStore,
ThemeStore: new ThemeStore,
ProductStore: new ProductStroe,
ChannelProudctStore: new ChannelProudctStore,
SiteStore: new SiteStore,
CategoryStore: new CategoryStore,
FilterStore: new FilterStore,
MemberStore: new MemberStore,
OrderStore: new OrderStore,
EvaluationStore: new EvaluationStore,
}
const MobxProvider: React.FC = (props) => {
return <Provider {...store}>{props.children}</Provider>
}
export default MobxProvider
\ No newline at end of file
import React from 'react';
import { Provider } from 'mobx-react'
import UserStore from './user'
import ThemeStore from './theme'
import ProductStroe from './product'
import OrderStore from './order'
import ChannelProudctStore from './channelProduct'
import SiteStore from './site'
import CategoryStore from './category'
import FilterStore from './filter'
import MemberStore from './member'
import BrowerHistoryStore from './browerHistory'
import EvaluationStore from './evaluation';
import { ILoginModule } from '@/module/userModule';
import { IProductModule } from '@/module/productModule'
import { IChannelProductModule } from '@/module/channelProductModule'
import { IMemberModule } from '@/module/memberModule';
import { IEvaluationModule } from '@/module/evaluationModule';
// import { ProductContext } from '@/pages/commodity/products/addProducts';
/**
*
* mobx使用说明
* @observable 只有被这个装饰后才能监听数据变化
* @computed 是根据@observable的数据计算属性
* @action 只能是同步处理数据,不能异步
* @action.bound 可以保证装饰的函数内部this永远指向当前store
* runInAction 是在action中做异步处理时需要调用的
*
* 官方文档:https://mobx.js.org/
* 中文文档:https://cn.mobx.js.org/
*
*
*/
export interface IStore {
UserStore: ILoginModule;
ProductStore: IProductModule;
ChannelProudctStore: IChannelProductModule;
MemberModuleStore: IMemberModule;
EvaluationModule: IEvaluationModule;
}
export const store = {
UserStore: new UserStore,
ThemeStore: new ThemeStore,
ProductStore: new ProductStroe,
ChannelProudctStore: new ChannelProudctStore,
SiteStore: new SiteStore,
CategoryStore: new CategoryStore,
FilterStore: new FilterStore,
MemberStore: new MemberStore,
OrderStore: new OrderStore,
EvaluationStore: new EvaluationStore,
BrowerHistoryStore: new BrowerHistoryStore,
}
const MobxProvider: React.FC = (props) => {
return <Provider {...store}>{props.children}</Provider>
}
export default MobxProvider
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