Commit 62482e2d authored by GuanHua's avatar GuanHua

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

parent e9a46aaa
.image_box { .image_box {
display: inline-block;
&_img { &_img {
background-size: 100% auto; background-size: 100% auto;
background-repeat: no-repeat; background-repeat: no-repeat;
...@@ -10,4 +12,10 @@ ...@@ -10,4 +12,10 @@
background-size: auto 100%; background-size: auto 100%;
} }
} }
&.circle {
.image_box_img {
border-radius: 50%;
}
}
} }
\ No newline at end of file
...@@ -8,15 +8,16 @@ interface ImageBoxPropsType { ...@@ -8,15 +8,16 @@ interface ImageBoxPropsType {
height?: number; height?: number;
imgUrl: string; imgUrl: string;
className?: any; className?: any;
direction?: "column" | "row" direction?: "column" | "row";
circle?: boolean
} }
const ImageBox: React.FC<ImageBoxPropsType> = (props) => { 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 ( 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 className={cx(styles.image_box_img, className)} style={{ backgroundImage: `url(${imgUrl})`, width: `${width}px`, height: `${height}px` }}></div>
</div> </div>
) )
......
import React, { useCallback } from 'react' import React, { useCallback, useEffect } from 'react'
import { Table } from 'antd' import { Table } from 'antd'
import { TableProps, ColumnsType, TablePaginationConfig } from 'antd/es/table' import { TableProps, ColumnsType, TablePaginationConfig } from 'antd/es/table'
import { CaretRightOutlined, CaretDownOutlined } from '@ant-design/icons' import { CaretRightOutlined, CaretDownOutlined } from '@ant-design/icons'
...@@ -36,7 +36,7 @@ const NestTable: React.FC<NestTableProps> = (props) => { ...@@ -36,7 +36,7 @@ const NestTable: React.FC<NestTableProps> = (props) => {
rowSelection={childRowSelection} rowSelection={childRowSelection}
pagination={childPagination} pagination={childPagination}
/> />
}, [childColumns, childrenDataKey]) }, [childColumns, childrenDataKey, childRowSelection])
return ( return (
<Table <Table
......
...@@ -13,6 +13,7 @@ fixed, ...@@ -13,6 +13,7 @@ fixed,
margin; margin;
@makeCentersLen: length(@makeCenters); @makeCentersLen: length(@makeCenters);
.loopCenter(@list, @i: 1, @val: extract(@list, @i)) when (@i < @makeCentersLen + 1) { .loopCenter(@list, @i: 1, @val: extract(@list, @i)) when (@i < @makeCentersLen + 1) {
.center-@{val} { .center-@{val} {
.make-center(@val); .make-center(@val);
...@@ -38,6 +39,12 @@ h6 { ...@@ -38,6 +39,12 @@ h6 {
color: #909399; color: #909399;
} }
a {
&:hover {
color: var(--mall_main_color) !important;
}
}
.tb_bg { .tb_bg {
background-color: #FAFBFC; background-color: #FAFBFC;
} }
......
import React from 'react' import React from 'react'
import cx from 'classnames'
import styles from './index.less' import styles from './index.less'
interface dataListType { interface dataListType {
label: string, label: string,
value: string | React.ReactNode, value: string | React.ReactNode,
labelClassName?: string,
required?: boolean required?: boolean
} }
...@@ -19,7 +21,7 @@ const InfoList: React.FC<InfoListProps> = (props) => { ...@@ -19,7 +21,7 @@ const InfoList: React.FC<InfoListProps> = (props) => {
{ {
data && data.map((item, index) => ( data && data.map((item, index) => (
<div className={styles.info_list_line} key={`info_list_line_${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 className={styles.info_list_line_value}>{item.value}</div>
</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 { Modal, Pagination } from 'antd'
import NestTable from '@/components/NestTable' import NestTable from '@/components/NestTable'
import { exchangeGoodsModalTableColumn, exchangeGoodsModalChildTableColumn } from '../../model/exchangeGoodsTable' import { exchangeGoodsModalTableColumn, exchangeGoodsModalChildTableColumn } from '../../model/exchangeGoodsTable'
...@@ -16,6 +16,8 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -16,6 +16,8 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
const [totalCount, setTotalCount] = useState<number>(4) const [totalCount, setTotalCount] = useState<number>(4)
const [current, setCurrent] = useState<number>(1) const [current, setCurrent] = useState<number>(1)
const [pageSize, setPageSize] = useState<number>(10) const [pageSize, setPageSize] = useState<number>(10)
const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<any>([])
const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<any>([])
const mockData = [ const mockData = [
{ {
...@@ -26,9 +28,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -26,9 +28,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08', createTime: '2020-05-12 08:08',
orderStatus: '已完成', orderStatus: '已完成',
orderType: '询价采购', orderType: '询价采购',
orderDeliveryProducts: [ childData: [
{ {
id: 1, id: 11,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -40,7 +42,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -40,7 +42,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000, replaceCount: 1000,
}, },
{ {
id: 2, id: 12,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -61,9 +63,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -61,9 +63,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08', createTime: '2020-05-12 08:08',
orderStatus: '已完成', orderStatus: '已完成',
orderType: '询价采购', orderType: '询价采购',
orderDeliveryProducts: [ childData: [
{ {
id: 3, id: 23,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -75,7 +77,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -75,7 +77,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000, replaceCount: 1000,
}, },
{ {
id: 4, id: 24,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -96,9 +98,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -96,9 +98,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08', createTime: '2020-05-12 08:08',
orderStatus: '已完成', orderStatus: '已完成',
orderType: '询价采购', orderType: '询价采购',
orderDeliveryProducts: [ childData: [
{ {
id: 5, id: 35,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -110,7 +112,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -110,7 +112,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000, replaceCount: 1000,
}, },
{ {
id: 6, id: 36,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -131,9 +133,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -131,9 +133,9 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
createTime: '2020-05-12 08:08', createTime: '2020-05-12 08:08',
orderStatus: '已完成', orderStatus: '已完成',
orderType: '询价采购', orderType: '询价采购',
orderDeliveryProducts: [ childData: [
{ {
id: 7, id: 47,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -145,7 +147,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -145,7 +147,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
replaceCount: 1000, replaceCount: 1000,
}, },
{ {
id: 8, id: 48,
productId: 1110, productId: 1110,
productName: '进口头层黄牛皮荔枝纹/红色', productName: '进口头层黄牛皮荔枝纹/红色',
category: '牛皮', category: '牛皮',
...@@ -160,6 +162,10 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -160,6 +162,10 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
}, },
] ]
useEffect(() => {
console.log(childSelectedRowKeys, "childSelectedRowKeys")
}, [childSelectedRowKeys])
const handleRowSelectionChangge = (selectedRowKeys, selectedRows) => { const handleRowSelectionChangge = (selectedRowKeys, selectedRows) => {
console.log(selectedRowKeys, selectedRows) console.log(selectedRowKeys, selectedRows)
} }
...@@ -208,6 +214,108 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -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 ( return (
<Modal <Modal
title="选择换货商品" title="选择换货商品"
...@@ -225,10 +333,17 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -225,10 +333,17 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
rowKey='id' rowKey='id'
className="common_tb" className="common_tb"
rowClassName={(_, index) => (index % 2) === 0 && "tb_bg"} rowClassName={(_, index) => (index % 2) === 0 && "tb_bg"}
childrenDataKey='orderDeliveryProducts' childrenDataKey='childData'
dataSource={mockData} dataSource={mockData}
childRowSelection={{ childRowSelection={{
onChange: handleRowSelectionChangge selectedRowKeys: childSelectedRowKeys,
onSelect: onChildSelectChange,
onSelectAll: onChildSelectAll,
}}
rowSelection={{
selectedRowKeys: parentSelectedRowKeys,
onSelect: onParentSelectChange,
onSelectAll: onParentSelectAll,
}} }}
/> />
</div> </div>
...@@ -239,6 +354,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => { ...@@ -239,6 +354,7 @@ const AddModal: React.FC<AddModalPropsType> = (props) => {
pageSize={pageSize} pageSize={pageSize}
current={current} current={current}
total={totalCount} total={totalCount}
onChange={handlePagination}
showTotal={total => `共 ${total} 条`} showTotal={total => `共 ${total} 条`}
/> />
</div> </div>
......
...@@ -10,7 +10,7 @@ interface ExchangeGoodsProps { ...@@ -10,7 +10,7 @@ interface ExchangeGoodsProps {
} }
const ExchangeGoods: React.FC<ExchangeGoodsProps> = (props) => { const ExchangeGoods: React.FC<ExchangeGoodsProps> = (props) => {
const [addVisible, setAddvisible] = useState<boolean>(true) const [addVisible, setAddvisible] = useState<boolean>(false)
const data = [ 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' ...@@ -6,6 +6,9 @@ import { Button, Tabs } from 'antd'
import ReutrnEle from '@/components/ReturnEle' import ReutrnEle from '@/components/ReturnEle'
import BasicInfo from './components/basicInfo' import BasicInfo from './components/basicInfo'
import ExchangeGoods from './components/exchangeGoods' 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' import styles from './detail.less'
interface OrderDetailProps { interface OrderDetailProps {
...@@ -46,7 +49,7 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => { ...@@ -46,7 +49,7 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => {
]} ]}
> >
<div className={styles.detail_wrap}> <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"> <TabPane tab="基本信息" key="basicInfo">
<BasicInfo /> <BasicInfo />
</TabPane> </TabPane>
...@@ -54,13 +57,13 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => { ...@@ -54,13 +57,13 @@ const OrderDetail: React.FC<OrderDetailProps> = (props) => {
<ExchangeGoods /> <ExchangeGoods />
</TabPane> </TabPane>
<TabPane tab="举证附件" key="proofFile"> <TabPane tab="举证附件" key="proofFile">
Content of Tab Pane 3 <ProofFile />
</TabPane> </TabPane>
<TabPane tab="换货收货地址" key="address"> <TabPane tab="换货收货地址" key="address">
Content of Tab Pane 3 <Address />
</TabPane> </TabPane>
<TabPane tab="流转记录" key="log"> <TabPane tab="流转记录" key="log">
Content of Tab Pane 3 <Log />
</TabPane> </TabPane>
</Tabs> </Tabs>
......
...@@ -255,11 +255,23 @@ const CommodityDetail = (props) => { ...@@ -255,11 +255,23 @@ const CommodityDetail = (props) => {
} }
if (clickFlag) { if (clickFlag) {
clickFlag = false clickFlag = false
let param = { let param: any = {
commodityUnitPriceId: selectCommodityId, commodityUnitPriceId: selectCommodityId,
count: buyCount 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 clickFlag = true
if (res.code === 1000) { if (res.code === 1000) {
message.destroy() message.destroy()
...@@ -339,8 +351,8 @@ const CommodityDetail = (props) => { ...@@ -339,8 +351,8 @@ const CommodityDetail = (props) => {
clickFlag = false clickFlag = false
PublicApi.postOrderDirectPayment({ productId: selectCommodityId }).then(res => { PublicApi.postOrderDirectPayment({ productId: selectCommodityId }).then(res => {
message.destroy()
if (res.code === 1000) { if (res.code === 1000) {
message.destroy()
let buyCommodityInfo = { let buyCommodityInfo = {
id: selectCommodityId, id: selectCommodityId,
count: buyCount, count: buyCount,
......
...@@ -7,6 +7,36 @@ ...@@ -7,6 +7,36 @@
width: 100%; width: 100%;
padding-top: 10px; 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 { .header_container {
.common_page_container(); .common_page_container();
height: 110px; height: 110px;
...@@ -52,20 +82,75 @@ ...@@ -52,20 +82,75 @@
} }
.mall_search_box { .mall_search_box {
display: flex;
.commone_input_placeholder(); .commone_input_placeholder();
position: relative; position: relative;
width: 100%; width: 100%;
border: 2px solid @mall_main_color; border: 2px solid @mall_main_color;
height: 40px; 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; display: inline-block;
width: 521px; flex: 1;
height: 36px; height: 36px;
line-height: 36px; line-height: 36px;
outline: none; outline: none;
border: none; border: none;
box-shadow: none;
} }
.search_btn { .search_btn {
......
...@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react' ...@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
import cx from 'classnames' import cx from 'classnames'
import { Input } from 'antd' import { Input } from 'antd'
import { history } from 'umi' import { history } from 'umi'
import { FileTextOutlined } from '@ant-design/icons' import { FileTextOutlined, DownOutlined } from '@ant-design/icons'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
import { PublicApi } from '@/services/api' import { PublicApi } from '@/services/api'
import { getAuth } from '@/utils/auth' import { getAuth } from '@/utils/auth'
...@@ -20,6 +20,13 @@ const Header: React.FC<HeaderPropsType> = (props) => { ...@@ -20,6 +20,13 @@ const Header: React.FC<HeaderPropsType> = (props) => {
const { search } = history.location.query const { search } = history.location.query
useEffect(() => { useEffect(() => {
// setTimeout(() => {
// let floatSearch = document.getElementById("floatSearch")
// floatSearch.classList.add(styles.show)
// }, 4000);
}, [])
useEffect(() => {
if (!!search) { if (!!search) {
setSearchValue(search) setSearchValue(search)
} else { } else {
...@@ -63,28 +70,58 @@ const Header: React.FC<HeaderPropsType> = (props) => { ...@@ -63,28 +70,58 @@ const Header: React.FC<HeaderPropsType> = (props) => {
} }
return ( return (
<div className={styles.header}> <>
<div className={styles.header_container}> <div className={styles.header}>
<div className={styles.logo}> <div className={styles.header_container}>
<img src={logo} /> <div className={styles.logo}>
</div> <img src={logo} />
<div className={styles.mall_search}> </div>
<div className={styles.mall_search_tags}> <div className={styles.mall_search}>
<div className={cx(styles.mall_search_tags_item, searchType === 1 ? styles.active : '')} onClick={() => handleChangeSearchType(1)}>商品</div> <div className={styles.mall_search_tags}>
<div className={cx(styles.mall_search_tags_item, searchType === 2 ? styles.active : '')} onClick={() => handleChangeSearchType(2)}>店铺</div> <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>
<div className={styles.mall_search_box}> <div className={cx(styles.shopping_cart, styles.mall)} onClick={() => history.push('/purchaseOrder')}>
<Input className={styles.mall_search_input} value={searchValue} placeholder="请输入关键词" onChange={e => setSearchValue(e.target.value)} onPressEnter={() => handleSearchCommodity()} /> <div className={styles.badge}>{count}</div>
<div className={styles.search_btn} onClick={() => handleSearchCommodity()}>搜索</div> <FileTextOutlined className={styles.card_icon} />
<span>进货单</span>
</div> </div>
</div> </div>
<div className={cx(styles.shopping_cart, styles.mall)} onClick={() => history.push('/purchaseOrder')}> </div>
<div className={styles.badge}>{count}</div>
<FileTextOutlined className={styles.card_icon} /> <div id="floatSearch" className={cx(styles.header, styles.float)}>
<span>进货单</span> <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> </div>
</div> </>
) )
} }
......
...@@ -121,7 +121,6 @@ ...@@ -121,7 +121,6 @@
&_item { &_item {
flex: 1; flex: 1;
text-align: center; text-align: center;
cursor: pointer;
&_count { &_count {
font-size: 20px; font-size: 20px;
...@@ -136,6 +135,7 @@ ...@@ -136,6 +135,7 @@
&>a { &>a {
color: #909399; color: #909399;
} }
} }
} }
...@@ -178,6 +178,12 @@ ...@@ -178,6 +178,12 @@
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
&:hover {
.quick_nav_list_item_text {
color: var(--mall_main_color);
}
}
&.bb { &.bb {
border-bottom: 1px solid #F4F5F7; border-bottom: 1px solid #F4F5F7;
} }
......
...@@ -117,7 +117,6 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => { ...@@ -117,7 +117,6 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
if (userInfo.memberRoleType === 1) { if (userInfo.memberRoleType === 1) {
component = <div className={styles.navList}> component = <div className={styles.navList}>
<div className={styles.navList_item}> <div className={styles.navList_item}>
<div className={styles.navList_item_count}>0</div> <div className={styles.navList_item_count}>0</div>
<div className={styles.navList_item_text}><a href={'/memberCenter/tranactionAbility/saleOrder/readyApprovedOrder'}>待审核</a></div> <div className={styles.navList_item_text}><a href={'/memberCenter/tranactionAbility/saleOrder/readyApprovedOrder'}>待审核</a></div>
</div> </div>
...@@ -162,9 +161,11 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => { ...@@ -162,9 +161,11 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
const goToLink = (path: string) => { const goToLink = (path: string) => {
if (userInfo) { if (userInfo) {
window.location.href = path // window.location.href = path
return path
} else { } 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) => { ...@@ -209,23 +210,23 @@ const QuickNav: React.FC<QuickNavPropsType> = (props) => {
<div className={styles.quick_nav_list}> <div className={styles.quick_nav_list}>
{ {
tabType === 1 ? sell_quick_nav_list.map((item, index) => ( 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} /> <img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span> <span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span> </a>
)) : buy_quick_nav_list.map((item, index) => ( )) : 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} /> <img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span> <span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span> </a>
)) ))
} }
{ {
quick_nav_list.map((item, index) => ( 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} /> <img className={styles.quick_nav_list_item_icon} src={item.icon} />
<span className={styles.quick_nav_list_item_text}>{item.title}</span> <span className={styles.quick_nav_list_item_text}>{item.title}</span>
</span> </a>
)) ))
} }
</div> </div>
......
...@@ -37,7 +37,7 @@ const Recommand: React.FC = () => { ...@@ -37,7 +37,7 @@ const Recommand: React.FC = () => {
<div className="recommand_list"> <div className="recommand_list">
{ {
product_list.map((item, index) => ( 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">
<div className="recommand_list_item_img"> <div className="recommand_list_item_img">
<img src={item.imgUrl} /> <img src={item.imgUrl} />
......
...@@ -30,6 +30,139 @@ ...@@ -30,6 +30,139 @@
padding: 0 16px; padding: 0 16px;
color: #303133; 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 { &.nopad {
padding: 0; padding: 0;
} }
......
import React from 'react' import React from 'react'
import { EnvironmentOutlined } from '@ant-design/icons' import { EnvironmentOutlined, CaretDownOutlined } from '@ant-design/icons'
import { inject, observer } from 'mobx-react' import { inject, observer } from 'mobx-react'
import cx from 'classnames' 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 { LAYOUT_TYPE } from '@/constants'
import { numFormat } from '@/utils/numberFomat'
import { removeAuth, removeRouters } from '@/utils/auth';
import styles from './index.less' import styles from './index.less'
interface TopBarPropsType { interface TopBarPropsType {
...@@ -29,6 +37,15 @@ const TopBar: React.FC<TopBarPropsType> = (props) => { ...@@ -29,6 +37,15 @@ const TopBar: React.FC<TopBarPropsType> = (props) => {
} }
} }
/**
* 退出登录
*/
const handleSignOut = () => {
removeAuth()
removeRouters()
window.location.replace('/user/login')
}
return ( return (
<div className={styles.topbar}> <div className={styles.topbar}>
<div className={styles.topbar_container}> <div className={styles.topbar_container}>
...@@ -47,16 +64,44 @@ const TopBar: React.FC<TopBarPropsType> = (props) => { ...@@ -47,16 +64,44 @@ const TopBar: React.FC<TopBarPropsType> = (props) => {
<ul className={cx(styles.topbar_menu, styles.right)}> <ul className={cx(styles.topbar_menu, styles.right)}>
{ {
userInfo ? ( userInfo ? (
<li className={styles.topbar_menu_item}> <li className={cx(styles.topbar_menu_item, styles.username)}>
<span>{userInfo?.name}</span> <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>
) : ( ) : (
<> <>
<li className={styles.topbar_menu_item}> <li className={styles.topbar_menu_item}>
<a href={`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`}>请登录</a> <a href={`/user/login?redirect=${btoa(encodeURIComponent(String(window.location)))}`} className={styles.login_link}>你好,请登录</a>
</li> <a href="/user/register">免费注册</a>
<li className={styles.topbar_menu_item}>
<a href="/user/register">注册</a>
</li> </li>
</> </>
) )
......
...@@ -37,8 +37,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => { ...@@ -37,8 +37,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
}, []) }, [])
const fetchPurchaseList = (initState = false) => { 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) { if (res.code === 1000) {
initPurchaseList(res.data, initState) initPurchaseList(res.data, initState)
} }
...@@ -179,11 +189,24 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => { ...@@ -179,11 +189,24 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
const handleCountChange = (count: number, id: number) => { const handleCountChange = (count: number, id: number) => {
if (countState) { if (countState) {
countState = false countState = false
let param = { let param: any = {
id, id,
count 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 countState = true
if (res.code === 1000) { if (res.code === 1000) {
message.destroy() message.destroy()
...@@ -243,7 +266,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => { ...@@ -243,7 +266,18 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
content: `是否从进货单中移除该商品?`, content: `是否从进货单中移除该商品?`,
onOk: () => { onOk: () => {
return new Promise((resolve, reject) => { 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) { if (res.code === 1000) {
// fetchPurchaseList() // fetchPurchaseList()
deleteListItems([id]) deleteListItems([id])
......
...@@ -96,7 +96,6 @@ const Commodity: React.FC = () => { ...@@ -96,7 +96,6 @@ const Commodity: React.FC = () => {
setCurrent(page) setCurrent(page)
} }
const handleCancelCollect = (detail) => { const handleCancelCollect = (detail) => {
Modal.confirm({ Modal.confirm({
centered: true, centered: true,
...@@ -111,7 +110,7 @@ const Commodity: React.FC = () => { ...@@ -111,7 +110,7 @@ const Commodity: React.FC = () => {
if ([3, 4, 5].includes(detail.type)) { if ([3, 4, 5].includes(detail.type)) {
param.channelMemberId = detail.channelMemberId param.channelMemberId = detail.channelMemberId
} }
console.log(param, "param")
PublicApi.postSearchShopCommodityCollectDeleteCommodityCollect(param).then(res => { PublicApi.postSearchShopCommodityCollectDeleteCommodityCollect(param).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
fetchCollectCommodityList() 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