Commit 62482e2d authored by GuanHua's avatar GuanHua

feat:修改企业商城样式和售后能力的一些页面

parent e9a46aaa
.image_box {
display: inline-block;
&_img {
background-size: 100% auto;
background-repeat: no-repeat;
......@@ -10,4 +12,10 @@
background-size: auto 100%;
}
}
&.circle {
.image_box_img {
border-radius: 50%;
}
}
}
\ No newline at end of file
......@@ -8,15 +8,16 @@ interface ImageBoxPropsType {
height?: number;
imgUrl: string;
className?: any;
direction?: "column" | "row"
direction?: "column" | "row";
circle?: boolean
}
const ImageBox: React.FC<ImageBoxPropsType> = (props) => {
const { width = 120, height = 80, imgUrl = "", className, direction = "row" } = props
const { width = 120, height = 80, imgUrl = "", className, direction = "row", circle = false } = props
return (
<div className={cx(styles.image_box, direction === 'column' ? styles.column : '')}>
<div className={cx(styles.image_box, direction === 'column' ? styles.column : '', circle ? styles.circle : '')}>
<div className={cx(styles.image_box_img, className)} style={{ backgroundImage: `url(${imgUrl})`, width: `${width}px`, height: `${height}px` }}></div>
</div>
)
......
import React, { useCallback } from 'react'
import React, { useCallback, useEffect } from 'react'
import { Table } from 'antd'
import { TableProps, ColumnsType, TablePaginationConfig } from 'antd/es/table'
import { CaretRightOutlined, CaretDownOutlined } from '@ant-design/icons'
......@@ -36,7 +36,7 @@ const NestTable: React.FC<NestTableProps> = (props) => {
rowSelection={childRowSelection}
pagination={childPagination}
/>
}, [childColumns, childrenDataKey])
}, [childColumns, childrenDataKey, childRowSelection])
return (
<Table
......
......@@ -13,6 +13,7 @@ fixed,
margin;
@makeCentersLen: length(@makeCenters);
.loopCenter(@list, @i: 1, @val: extract(@list, @i)) when (@i < @makeCentersLen + 1) {
.center-@{val} {
.make-center(@val);
......@@ -38,6 +39,12 @@ h6 {
color: #909399;
}
a {
&:hover {
color: var(--mall_main_color) !important;
}
}
.tb_bg {
background-color: #FAFBFC;
}
......
import React from 'react'
import cx from 'classnames'
import styles from './index.less'
interface dataListType {
label: string,
value: string | React.ReactNode,
labelClassName?: string,
required?: boolean
}
......@@ -19,7 +21,7 @@ const InfoList: React.FC<InfoListProps> = (props) => {
{
data && data.map((item, index) => (
<div className={styles.info_list_line} key={`info_list_line_${index}`}>
<div className={styles.info_list_line_label}>{item.label}{item.required && <i className={styles.required}>*</i>}</div>
<div className={cx(styles.info_list_line_label, item.labelClassName ? item.labelClassName : "")}>{item.label}{item.required && <i className={styles.required}>*</i>}</div>
<div className={styles.info_list_line_value}>{item.value}</div>
</div>
))
......
import React from 'react'
interface AddressPropsType {
}
const Address: React.FC<AddressPropsType> = (props) => {
return (
<div>
</div>
)
}
export default Address
import React, { useState } from 'react'
import React, { useState, useEffect } from 'react'
import { Modal, Pagination } from 'antd'
import NestTable from '@/components/NestTable'
import { exchangeGoodsModalTableColumn, exchangeGoodsModalChildTableColumn } from '../../model/exchangeGoodsTable'
......@@ -16,6 +16,8 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
const [totalCount, setTotalCount] = useState<number>(4)
const [current, setCurrent] = useState<number>(1)
const [pageSize, setPageSize] = useState<number>(10)
const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<any>([])
const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<any>([])
const mockData = [
{
......@@ -26,9 +28,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08',
orderStatus: '已完成',
orderType: '询价采购',
orderDeliveryProducts: [
childData: [
{
id: 1,
id: 11,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -40,7 +42,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000,
},
{
id: 2,
id: 12,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -61,9 +63,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08',
orderStatus: '已完成',
orderType: '询价采购',
orderDeliveryProducts: [
childData: [
{
id: 3,
id: 23,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -75,7 +77,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000,
},
{
id: 4,
id: 24,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -96,9 +98,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08',
orderStatus: '已完成',
orderType: '询价采购',
orderDeliveryProducts: [
childData: [
{
id: 5,
id: 35,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -110,7 +112,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000,
},
{
id: 6,
id: 36,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -131,9 +133,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08',
orderStatus: '已完成',
orderType: '询价采购',
orderDeliveryProducts: [
childData: [
{
id: 7,
id: 47,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -145,7 +147,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000,
},
{
id: 8,
id: 48,
productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮',
......@@ -160,6 +162,10 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
},
]
useEffect(() => {
console.log(childSelectedRowKeys, "childSelectedRowKeys")
}, [childSelectedRowKeys])
const handleRowSelectionChangge = (selectedRowKeys, selectedRows) => {
console.log(selectedRowKeys, selectedRows)
}
......@@ -208,6 +214,108 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
]
}
const onParentSelectChange = (record: any, selected: any, selectedRows: any) => {
let patentArr: any = [...parentSelectedRowKeys];
let childArr: any = [...childSelectedRowKeys];
//setChildArr:选择父Table下的所有子选项
let setChildArr = mockData.find((d: any) => d.id === record.id).childData.map((item: any) => item.id)
//第一步 判断selected true:选中,false,取消选中
if (selected) {
//第二步,父Table选中,子Table全选中(全部整合到一起,然后去重)
patentArr.push(record.id)
childArr = Array.from(new Set([...setChildArr, ...childArr]))
} else {
//第二步,父Table取消选中,子Table全取消选中(针对childArr,过滤掉取消选中的父Table下的所有子Table的key)
patentArr.splice(patentArr.findIndex((item: any) => item === record.id), 1)
childArr = childArr.filter((item: any) => !setChildArr.some((e: any) => e === item))
}
//第三步,设置父,子的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
setChildSelectedRowKeys(childArr)
}
const onParentSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
let patentArr: any = [...parentSelectedRowKeys];
let setChildArr: any = [];
//将改变的父Table下的子Table下的key都添加到setChildArr中
changeRows.forEach((e: any) => {
setChildArr = [...setChildArr, ...e.childData.map((item: any) => item.id)]
});
//第一步判断selected true:全选,false:取消全选
if (selected) {
//第二步:父Table选中,子Table全选中,设置子Table的SelectedRowKeys
patentArr = Array.from(new Set([...patentArr, ...changeRows.map((item: any) => item.id)]))
setChildSelectedRowKeys(setChildArr)
} else {
//第二步:父Table取消选中,子Table全取消选中,设置子Table的SelectedRowKeys
patentArr = patentArr.filter((item: any) => !changeRows.some((e: any) => e.id === item))
setChildSelectedRowKeys([])
}
//第三步:设置父Table的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
}
const onChildSelectChange = (record: any, selected: any, selectedRows: any) => {
let childArr: any = [...childSelectedRowKeys];
//第一步 判断selected true:选中,将key值添加到childArr,false:取消选中,将key值从childArr中移除
if (selected) {
childArr.push(record.id)
} else {
childArr.splice(childArr.findIndex((item: any) => item === record.id), 1)
}
//必须去除undefined,否则selectedRows会将其他子Table中选中的key值放到数组中,但是值为undefined,如:[ undefined,1,uundefined]
selectedRows = selectedRows.filter((a: any) => a !== undefined)
//第二步,判断selectedRows的长度是否为data中child的长度,相等,就将父table选中,不等就不选中
for (let item of mockData) {
if (item.childData.find((d: any) => d.id === record.id)) {
let parentArr: any = [...parentSelectedRowKeys];
if (item.childData.length === selectedRows.length) {
parentArr.push(item.id)
} else {
if (parentArr.length && parentArr.find((d: any) => d === item.id)) {
parentArr.splice(parentArr.findIndex((item1: any) => item1 === item.id), 1)
}
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
const onChildSelectAll = (selected: any, selectedRows: any, changeRows: any) => {
//第一步:判断selected,true:将子Table全部选中,false:将子Table全部取消选中
let childArr: any = [...childSelectedRowKeys];
if (selected) {
//全选
childArr = Array.from(new Set([...childArr, ...changeRows.map((item: any) => item.id)]))
} else {
//取消全选
childArr = childArr.filter((item: any) => !changeRows.some((e: any) => e.id === item))
}
//第二步:找到子Table对应的父Table的所在行,再判断selected,true:将父Table所在行选中,false:将父Table所在行取消选中
for (let item of mockData) {
if (item.childData.find((d: any) => d.id === changeRows[0].id)) {
let parentArr: any = [...parentSelectedRowKeys];
if (selected) {
//全选
parentArr.push(item.id)
} else {
//取消全选
parentArr.splice(parentArr.findIndex((item: any) => item === item.id), 1)
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
const handlePagination = () => {
}
return (
<Modal
title="选择换货商品"
......@@ -225,10 +333,17 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
rowKey='id'
className="common_tb"
rowClassName={(_, index) => (index % 2) === 0 && "tb_bg"}
childrenDataKey='orderDeliveryProducts'
childrenDataKey='childData'
dataSource={mockData}
childRowSelection={{
onChange: handleRowSelectionChangge
selectedRowKeys: childSelectedRowKeys,
onSelect: onChildSelectChange,
onSelectAll: onChildSelectAll,
}}
rowSelection={{
selectedRowKeys: parentSelectedRowKeys,
onSelect: onParentSelectChange,
onSelectAll: onParentSelectAll,
}}
/>
</div>
......@@ -239,6 +354,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
pageSize={pageSize}
current={current}
total={totalCount}
onChange={handlePagination}
showTotal={total => `共 ${total} 条`}
/>
</div>
......
......@@ -10,7 +10,7 @@ interface ExchangeGoodsProps {
}
const ExchangeGoods: React.FC<ExchangeGoodsProps> = (props) => {
const [addVisible, setAddvisible] = useState<boolean>(true)
const [addVisible, setAddvisible] = useState<boolean>(false)
const data = [
{
......
import React from 'react'
interface LogPropsType {
}
const Log: React.FC<LogPropsType> = (props) => {
return (
<div>
</div>
)
}
export default Log
.upload_tip {
font-size: 12px;
color: #909399;
margin-top: 12px;
}
.flexStart {
position: relative;
align-self: flex-start;
}
.upload_btn {
margin-top: 8px;
}
.file_list {
&_item {
width: 572px;
height: 32px;
display: flex;
align-items: center;
background: #F4F5F7;
border-radius: 4px;
margin-bottom: 8px;
color: #00B37A;
padding: 0 8px;
.file_type {
margin-right: 4px;
&>img {
width: 20px;
height: 20px;
}
}
.del_btn {
color: #909399;
font-size: 14px;
cursor: pointer;
margin-left: auto;
}
}
}
\ No newline at end of file
import React, { useState } from 'react'
import { UploadOutlined, DeleteOutlined } from '@ant-design/icons'
import InfoList from '../../../../components/InfoList'
import { Button, Upload, message } from 'antd'
import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface'
import fileTypeDoc from './imgs/file_type_doc.png'
import fileTypeOther from './imgs/file_type_other.png'
import fileTypePhoto from './imgs/file_type_photo.png'
import { UPLOAD_TYPE } from '@/constants'
import styles from './index.less'
interface ProofFilePropsType {
}
const mock = [{
id: 1,
fileName: '验货详情.doc',
filePath: '',
},
{
id: 2,
fileName: '不良情况.png',
filePath: '',
},
{
id: 3,
fileName: '其他.other',
filePath: '',
}]
const docFileTypeList = ['doc', 'docx', 'docm', 'xlsx', 'xlsm', 'pptx', 'xls']
const photoFileTypeList = ['png', 'jpg', 'jpeg', 'gif']
const ProofFile: React.FC<ProofFilePropsType> = (props) => {
const [fileList, setFileList] = useState<any>(mock)
const [loading, setLoading] = useState<boolean>(false)
const fileMaxSize = 1024 * 20
const beforeUpload = (file: UploadFile) => {
const isSizeLimit = file.size / 1024 < fileMaxSize;
if (!isSizeLimit) {
message.error(`附件大小不能超过 20M`);
}
return isSizeLimit;
}
const uploadProps = {
name: 'file',
action: '/api/file/file/upload',
headers: {},
data: {
fileType: UPLOAD_TYPE
},
disabled: loading,
showUploadList: false,
onChange(info: UploadChangeParam) {
if (info.file.status === 'uploading') {
setLoading(true)
return;
}
if (info.file.status === 'done') {
// 图片回显
const { code, data } = info.file.response
if (code === 1000) {
console.log('upload success')
let newFileArr = [...fileList]
newFileArr.push({
fileName: info.file.name,
filePath: data
})
setFileList(newFileArr)
}
setLoading(false)
}
},
beforeUpload
};
const getFileTypeByName = (fileName: string) => {
if (fileName && typeof fileName === 'string') {
let fileType = fileName.split('.')[1]
if (fileType) {
if (docFileTypeList.includes(fileType)) {
return <img src={fileTypeDoc} />
} else if (photoFileTypeList.includes(fileType)) {
return <img src={fileTypePhoto} />
} else {
return <img src={fileTypeOther} />
}
}
}
}
const handleDeleteFileItem = (index: number) => {
let newFileList = [...fileList]
newFileList.splice(index, 1)
setFileList(newFileList)
}
let detailList = [
{
label: '附件',
labelClassName: styles.flexStart,
value: <>
<div className={styles.file_list}>
{
fileList && fileList.map((item, index) => (
<div key={`file_list_item_${index}`} className={styles.file_list_item}>
<i className={styles.file_type}>
{
getFileTypeByName(item.fileName)
}
</i>
<span>{item.fileName}</span>
<DeleteOutlined className={styles.del_btn} onClick={() => handleDeleteFileItem(index)} />
</div>
))
}
</div>
<Upload {...uploadProps}>
<Button icon={<UploadOutlined />} className={styles.upload_btn}>上传文件</Button>
</Upload>
<p className={styles.upload_tip}>一次上传一个文件,每个附件大小不能超过 20M</p>
</>,
},
]
return (
<div>
<InfoList data={detailList} />
</div>
)
}
export default ProofFile
......@@ -6,6 +6,9 @@ import { Button, Tabs } from 'antd'
import ReutrnEle from '@/components/ReturnEle'
import BasicInfo from './components/basicInfo'
import ExchangeGoods from './components/exchangeGoods'
import ProofFile from './components/proofFile'
import Log from './components/log'
import Address from './components/address'
import styles from './detail.less'
interface OrderDetailProps {
......@@ -46,7 +49,7 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => {
]}
>
<div className={styles.detail_wrap}>
<Tabs type="card" defaultActiveKey="exchangeGoods" className={styles.detail_tabs}>
<Tabs type="card" defaultActiveKey="proofFile" className={styles.detail_tabs}>
<TabPane tab="基本信息" key="basicInfo">
<BasicInfo />
</TabPane>
......@@ -54,13 +57,13 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => {
<ExchangeGoods />
</TabPane>
<TabPane tab="举证附件" key="proofFile">
Content of Tab Pane 3
<ProofFile />
</TabPane>
<TabPane tab="换货收货地址" key="address">
Content of Tab Pane 3
<Address />
</TabPane>
<TabPane tab="流转记录" key="log">
Content of Tab Pane 3
<Log />
</TabPane>
</Tabs>
......
......@@ -255,11 +255,23 @@ const CommodityDetail = (props) => {
}
if (clickFlag) {
clickFlag = false
let param = {
let param: any = {
commodityUnitPriceId: selectCommodityId,
count: buyCount
}
PublicApi.postSearchShopPurchaseSaveOrUpdatePurchase(param).then(res => {
let postFn
switch (layoutType) {
case LAYOUT_TYPE.channel:
case LAYOUT_TYPE.ichannel:
param.commodityType = 2
postFn = PublicApi.postSearchShopPurchaseChannelSaveOrUpdatePurchase
break;
default:
postFn = PublicApi.postSearchShopPurchaseSaveOrUpdatePurchase
break;
}
postFn && postFn(param).then(res => {
clickFlag = true
if (res.code === 1000) {
message.destroy()
......@@ -339,8 +351,8 @@ const CommodityDetail = (props) => {
clickFlag = false
PublicApi.postOrderDirectPayment({ productId: selectCommodityId }).then(res => {
message.destroy()
if (res.code === 1000) {
message.destroy()
let buyCommodityInfo = {
id: selectCommodityId,
count: buyCount,
......
......@@ -7,6 +7,36 @@
width: 100%;
padding-top: 10px;
:global {
.show {
transform: translateY(0) !important;
}
}
&.float {
position: fixed;
transform: translateY(-100px);
top: 0;
left: 0;
z-index: 999;
border-bottom: 1px solid var(--mall_main_color);
padding-top: 0;
transition: all .5s;
&.show {
transform: translateY(0) !important;
}
.header_container {
height: 56px;
}
.shopping_cart {
margin-top: 0px !important;
}
}
.header_container {
.common_page_container();
height: 110px;
......@@ -52,20 +82,75 @@
}
.mall_search_box {
display: flex;
.commone_input_placeholder();
position: relative;
width: 100%;
border: 2px solid @mall_main_color;
height: 40px;
.mall_search_input {
.search_type {
position: relative;
&:hover {
.more_type {
display: block;
}
}
&_item {
position: relative;
display: flex;
align-items: center;
width: 70px;
margin: 8px 0;
text-align: center;
font-size: 12px;
padding-left: 15px;
color: #909399;
border-right: 1px solid #EEF0F3;
&_text {
margin-right: 6px;
}
&_icon {
font-size: 10px;
}
}
.more_type {
position: absolute;
display: none;
top: 36px;
left: -2px;
border-top: 2px solid var(--mall_main_color);
background: #FFFFFF;
width: 72px;
height: 32px;
line-height: 32px;
z-index: 9999;
font-size: 12px;
padding-left: 15px;
color: #909399;
cursor: pointer;
&:hover {
color: var(--mall_main_color);
}
}
}
.mall_search_input {
display: inline-block;
width: 521px;
flex: 1;
height: 36px;
line-height: 36px;
outline: none;
border: none;
box-shadow: none;
}
.search_btn {
......
......@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
import cx from 'classnames'
import { Input } from 'antd'
import { history } from 'umi'
import { FileTextOutlined } from '@ant-design/icons'
import { FileTextOutlined, DownOutlined } from '@ant-design/icons'
import isEmpty from 'lodash/isEmpty'
import { PublicApi } from '@/services/api'
import { getAuth } from '@/utils/auth'
......@@ -20,6 +20,13 @@ const Header: React.FC<HeaderPropsType> = (props) => {
const { search } = history.location.query
useEffect(() => {
// setTimeout(() => {
// let floatSearch = document.getElementById("floatSearch")
// floatSearch.classList.add(styles.show)
// }, 4000);
}, [])
useEffect(() => {
if (!!search) {
setSearchValue(search)
} else {
......@@ -63,28 +70,58 @@ const Header: React.FC<HeaderPropsType> = (props) => {
}
return (
<div className={styles.header}>
<div className={styles.header_container}>
<div className={styles.logo}>
<img src={logo} />
</div>
<div className={styles.mall_search}>
<div className={styles.mall_search_tags}>
<div className={cx(styles.mall_search_tags_item, searchType === 1 ? styles.active : '')} onClick={() => handleChangeSearchType(1)}>商品</div>
<div className={cx(styles.mall_search_tags_item, searchType === 2 ? styles.active : '')} onClick={() => handleChangeSearchType(2)}>店铺</div>
<>
<div className={styles.header}>
<div className={styles.header_container}>
<div className={styles.logo}>
<img src={logo} />
</div>
<div className={styles.mall_search}>
<div className={styles.mall_search_tags}>
<div className={cx(styles.mall_search_tags_item, searchType === 1 ? styles.active : '')} onClick={() => handleChangeSearchType(1)}>商品</div>
<div className={cx(styles.mall_search_tags_item, searchType === 2 ? styles.active : '')} onClick={() => handleChangeSearchType(2)}>店铺</div>
</div>
<div className={styles.mall_search_box}>
<Input className={styles.mall_search_input} value={searchValue} placeholder="请输入关键词" onChange={e => setSearchValue(e.target.value)} onPressEnter={() => handleSearchCommodity()} />
<div className={styles.search_btn} onClick={() => handleSearchCommodity()}>搜索</div>
</div>
</div>
<div className={styles.mall_search_box}>
<Input className={styles.mall_search_input} value={searchValue} placeholder="请输入关键词" onChange={e => setSearchValue(e.target.value)} onPressEnter={() => handleSearchCommodity()} />
<div className={styles.search_btn} onClick={() => handleSearchCommodity()}>搜索</div>
<div className={cx(styles.shopping_cart, styles.mall)} onClick={() => history.push('/purchaseOrder')}>
<div className={styles.badge}>{count}</div>
<FileTextOutlined className={styles.card_icon} />
<span>进货单</span>
</div>
</div>
<div className={cx(styles.shopping_cart, styles.mall)} onClick={() => history.push('/purchaseOrder')}>
<div className={styles.badge}>{count}</div>
<FileTextOutlined className={styles.card_icon} />
<span>进货单</span>
</div>
<div id="floatSearch" className={cx(styles.header, styles.float)}>
<div className={styles.header_container}>
<div className={styles.logo}>
<img src={logo} />
</div>
<div className={styles.mall_search}>
<div className={styles.mall_search_box}>
<div className={styles.search_type}>
<div className={styles.search_type_item}>
<span className={styles.search_type_item_text}>{searchType === 1 ? '商品' : '店铺'}</span>
<DownOutlined className={styles.search_type_item_icon} />
</div>
<div className={styles.more_type} onClick={() => handleChangeSearchType(searchType === 1 ? 2 : 1)}>
<span className={styles.search_type_item_text}>{searchType === 1 ? '店铺' : '商品'}</span>
</div>
</div>
<Input className={styles.mall_search_input} value={searchValue} placeholder="请输入关键词" onChange={e => setSearchValue(e.target.value)} onPressEnter={() => handleSearchCommodity()} />
<div className={styles.search_btn} onClick={() => handleSearchCommodity()}>搜索</div>
</div>
</div>
<div className={cx(styles.shopping_cart, styles.mall)} onClick={() => history.push('/purchaseOrder')}>
<div className={styles.badge}>{count}</div>
<FileTextOutlined className={styles.card_icon} />
<span>进货单</span>
</div>
</div>
</div>
</div>
</>
)
}
......
......@@ -121,7 +121,6 @@
&_item {
flex: 1;
text-align: center;
cursor: pointer;
&_count {
font-size: 20px;
......@@ -136,6 +135,7 @@
&>a {
color: #909399;
}
}
}
......@@ -178,6 +178,12 @@
justify-content: center;
cursor: pointer;
&:hover {
.quick_nav_list_item_text {
color: var(--mall_main_color);
}
}
&.bb {
border-bottom: 1px solid #F4F5F7;
}
......
......@@ -117,7 +117,6 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
if (userInfo.memberRoleType === 1) {
component = <div className={styles.navList}>
<div className={styles.navList_item}>
<div className={styles.navList_item_count}>0</div>
<div className={styles.navList_item_text}><a href={'/memberCenter/tranactionAbility/saleOrder/readyApprovedOrder'}>待审核</a></div>
</div>
......@@ -162,9 +161,11 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
const goToLink = (path: string) => {
if (userInfo) {
window.location.href = path
// window.location.href = path
return path
} else {
window.location.href = `/user/login?redirect=${btoa(encodeURIComponent(String(path)))}`
// window.location.href = `/user/login?redirect=${btoa(encodeURIComponent(String(path)))}`
return `/user/login?redirect=${btoa(encodeURIComponent(String(path)))}`
}
}
......@@ -209,23 +210,23 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
<div className={styles.quick_nav_list}>
{
tabType === 1 ? sell_quick_nav_list.map((item, index) => (
<span onClick={() => goToLink(item.path)} className={cx(styles.quick_nav_list_item, styles.bb)} key={`sell_quick_nav_list_item-${index}`}>
<a href={goToLink(item.path)} className={cx(styles.quick_nav_list_item, styles.bb)} key={`sell_quick_nav_list_item-${index}`}>
<img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span>
</a>
)) : buy_quick_nav_list.map((item, index) => (
<span onClick={() => goToLink(item.path)} className={cx(styles.quick_nav_list_item, styles.bb)} key={`buy_quick_nav_list_item-${index}`}>
<a href={goToLink(item.path)} className={cx(styles.quick_nav_list_item, styles.bb)} key={`buy_quick_nav_list_item-${index}`}>
<img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span>
</a>
))
}
{
quick_nav_list.map((item, index) => (
<span onClick={() => goToLink(item.path)} className={styles.quick_nav_list_item} key={`quick_nav_list_item-${index}`}>
<a href={goToLink(item.path)} className={styles.quick_nav_list_item} key={`quick_nav_list_item-${index}`}>
<img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span>
</a>
))
}
</div>
......
......@@ -37,7 +37,7 @@ const Recommand: React.FC = () => {
<div className="recommand_list">
{
product_list.map((item, index) => (
<a href="/shop/commodity/detail?id=asdjflewjfe&type=prompt" key={`recommand_list_item_${index}`}>
<a href="/" key={`recommand_list_item_${index}`}>
<div className="recommand_list_item">
<div className="recommand_list_item_img">
<img src={item.imgUrl} />
......
......@@ -30,6 +30,139 @@
padding: 0 16px;
color: #303133;
&.username {
position: relative;
cursor: pointer;
border-left: 1px solid #ffffff;
border-right: 1px solid #ffffff;
&:hover {
border-left: 1px solid #EEF0F3;
border-right: 1px solid #EEF0F3;
.username {
color: var(--mall_main_color);
}
.arrow_icon {
color: #303133;
}
.userInfo_card_split,
.userInfo_card {
display: block;
}
&::after {
display: none;
}
}
}
.userInfo_card_split {
display: none;
position: absolute;
top: 29px;
left: 0;
height: 2px;
width: 100%;
background: #FFFFFF;
z-index: 999;
}
.userInfo_card {
display: none;
position: absolute;
width: 400px;
height: 200px;
top: 30px;
left: 0;
background: #FFFFFF;
z-index: 99;
box-shadow: 0px 2px 8px 0px rgba(48, 49, 51, 0.08), 0px 0px 1px 0px #EEF0F3;
border: 1px solid #EEF0F3;
&_header {
display: flex;
align-items: center;
padding: 24px 0 16px 0;
margin: 0 24px;
border-bottom: 1px solid #EEF0F3;
}
&_column {
margin-left: 16px;
.userInfo_card_level {
width: 54px;
height: 16px;
background-repeat: no-repeat;
background-size: cover;
&.level3 {
background-image: url(/static/imgs/level3@2x.png);
}
&.level2 {
background-image: url(/static/imgs/level1@2x.png);
}
&.level1 {
background-image: url(/static/imgs/level2@2x.png);
}
}
}
.nav_list {
display: flex;
padding: 15px 24px 0 24px;
justify-content: space-between;
&_item {
text-align: center;
&:hover {
span {
color: var(--mall_main_color);
}
}
&>img {
display: block;
margin: 0 auto;
width: 40px;
height: 40px;
}
&>span {
line-height: 12px;
margin-top: 12px;
}
}
}
.sign_out_btn {
cursor: pointer;
margin-left: auto;
&:hover {
color: var(--mall_main_color);
}
}
}
.login_link {
color: var(--mall_main_color);
margin-right: 10px;
}
.arrow_icon {
margin-left: 8px;
color: #909399;
}
&.nopad {
padding: 0;
}
......
import React from 'react'
import { EnvironmentOutlined } from '@ant-design/icons'
import { EnvironmentOutlined, CaretDownOutlined } from '@ant-design/icons'
import { inject, observer } from 'mobx-react'
import cx from 'classnames'
import ImageBox from '@/components/ImageBox'
import defaultAvatar from './imgs/default_avatar.png'
import AccountSafeIcon from './imgs/account_safe_icon.png'
import capitalAccountIcon from './imgs/capital_account.png'
import memberBenefitsIcon from './imgs/member_benefits_icon.png'
import memberInfoIcon from './imgs/member_info_icon.png'
import { LAYOUT_TYPE } from '@/constants'
import { numFormat } from '@/utils/numberFomat'
import { removeAuth, removeRouters } from '@/utils/auth';
import styles from './index.less'
interface TopBarPropsType {
......@@ -29,6 +37,15 @@ const TopBar: React.FC<TopBarPropsType> = (props) => {
}
}
/**
* 退出登录
*/
const handleSignOut = () => {
removeAuth()
removeRouters()
window.location.replace('/user/login')
}
return (
<div className={styles.topbar}>
<div className={styles.topbar_container}>
......@@ -47,16 +64,44 @@ const TopBar: React.FC<TopBarPropsType> = (props) => {
<ul className={cx(styles.topbar_menu, styles.right)}>
{
userInfo ? (
<li className={styles.topbar_menu_item}>
<span>{userInfo?.name}</span>
<li className={cx(styles.topbar_menu_item, styles.username)}>
<span className={styles.username}>{userInfo?.name}</span>
<CaretDownOutlined className={styles.arrow_icon} />
<div className={styles.userInfo_card_split}></div>
<div className={styles.userInfo_card}>
<div className={styles.userInfo_card_header}>
<ImageBox width={64} height={64} circle={true} direction="column" imgUrl={defaultAvatar} />
<div className={styles.userInfo_card_column}>
<div>信用积分:<span>{numFormat(1278)}</span></div>
<div className={cx(styles.userInfo_card_level, styles.level3)} />
</div>
<div className={styles.sign_out_btn} onClick={handleSignOut}>退出账号</div>
</div>
<div className={styles.nav_list}>
<div className={styles.nav_list_item}>
<img src={AccountSafeIcon} />
<span>账户安全</span>
</div>
<div className={styles.nav_list_item}>
<img src={memberInfoIcon} />
<span>会员信息</span>
</div>
<div className={styles.nav_list_item}>
<img src={capitalAccountIcon} />
<span>资金账户</span>
</div>
<div className={styles.nav_list_item}>
<img src={memberBenefitsIcon} />
<span>会员权益</span>
</div>
</div>
</div>
</li>
) : (
<>
<li className={styles.topbar_menu_item}>
<a href={`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`}>请登录</a>
</li>
<li className={styles.topbar_menu_item}>
<a href="/user/register">注册</a>
<a href={`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`} className={styles.login_link}>你好,请登录</a>
<a href="/user/register">免费注册</a>
</li>
</>
)
......
......@@ -37,8 +37,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
}, [])
const fetchPurchaseList = (initState = false) => {
let getFn
switch (layoutType) {
case LAYOUT_TYPE.channel:
case LAYOUT_TYPE.ichannel:
getFn = PublicApi.getSearchShopPurchaseChannelGetPurchaseList
break;
default:
getFn = PublicApi.getSearchShopPurchaseGetPurchaseList
break;
}
PublicApi.getSearchShopPurchaseGetPurchaseList().then(res => {
getFn && getFn().then(res => {
if (res.code === 1000) {
initPurchaseList(res.data, initState)
}
......@@ -179,11 +189,24 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
const handleCountChange = (count: number, id: number) => {
if (countState) {
countState = false
let param = {
let param: any = {
id,
count
}
PublicApi.postSearchShopPurchaseSaveOrUpdatePurchase(param).then(res => {
let postFn
switch (layoutType) {
case LAYOUT_TYPE.channel:
case LAYOUT_TYPE.ichannel:
param.commodityType = 2
postFn = PublicApi.postSearchShopPurchaseChannelSaveOrUpdatePurchase
break
default:
postFn = PublicApi.postSearchShopPurchaseSaveOrUpdatePurchase
break;
}
postFn && postFn(param).then(res => {
countState = true
if (res.code === 1000) {
message.destroy()
......@@ -243,7 +266,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
content: `是否从进货单中移除该商品?`,
onOk: () => {
return new Promise((resolve, reject) => {
PublicApi.postSearchShopPurchaseDeletePurchase({ idList: [id] }).then(res => {
let postFn
switch (layoutType) {
case LAYOUT_TYPE.channel:
case LAYOUT_TYPE.ichannel:
postFn = PublicApi.postSearchShopPurchaseChannelDeletePurchase
break
default:
postFn = PublicApi.postSearchShopPurchaseDeletePurchase
break;
}
postFn && postFn({ idList: [id] }).then(res => {
if (res.code === 1000) {
// fetchPurchaseList()
deleteListItems([id])
......
......@@ -96,7 +96,6 @@ const Commodity: React.FC = () => {
setCurrent(page)
}
const handleCancelCollect = (detail) => {
Modal.confirm({
centered: true,
......@@ -111,7 +110,7 @@ const Commodity: React.FC = () => {
if ([3, 4, 5].includes(detail.type)) {
param.channelMemberId = detail.channelMemberId
}
console.log(param, "param")
PublicApi.postSearchShopCommodityCollectDeleteCommodityCollect(param).then(res => {
if (res.code === 1000) {
fetchCollectCommodityList()
......
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