Commit f1ec16f5 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

Merge branch 'dev' into test

parents f9d3479e 2225cf69
......@@ -127,6 +127,13 @@ const LogisticsRoute: RouterChild = {
path: '/memberCenter/logisticsAbility/logisticsSubmit',
name: 'logisticsSubmit',
routes: [
// 新增
{
path: '/memberCenter/logisticsAbility/logisticsSubmit/addLogistics',
name: 'addToOrderSubmit',
component: '@/pages/logistics/addLogistics',
hideInMenu: true
},
// 快递单查询
{
path: '/memberCenter/logisticsAbility/logisticsSubmit/orderSubmitSearchList',
......
......@@ -3,7 +3,7 @@ import {StandardTable} from 'god';
import NestTable from '@/components/NestTable';
import { IStandardTableProps } from 'god/dist/src/standard-table';
import { Row, Col, Modal } from 'antd';
import { productModalSchema, productModalByMemberSchema, memberModalSchema, inquirySchema, demandSchema, enquirySchema, mergeOrderSchema, goodsModalSchema, demandNumberSchema, logisticsDeliverySearchSchema, addOrderModalSchema } from './schema';
import { productModalSchema, productModalByMemberSchema, memberModalSchema, inquirySchema, demandSchema, enquirySchema, mergeOrderSchema, goodsModalSchema, demandNumberSchema, logisticsDeliverySearchSchema, addOrderModalSchema , logisticsSelectGoodsSearchSchema} from './schema';
import Search from '../NiceForm/components/Search';
import SearchSelect from '../NiceForm/components/SearchSelect';
import Submit from '../NiceForm/components/Submit';
......@@ -18,7 +18,7 @@ export interface ModalTableProps extends IStandardTableProps<any> {
cancel?(),
visible?: boolean,
resetModal?: object,
modalType?: 'productByDefault' | 'productByMember' | 'memberByDefault' | 'inquiryByDefault' | 'demandByDefault' | 'enquiryModel' | 'MergeOrderByDefault' | 'goodsModalSchema' | 'demandNumberSchema' | 'logisticsDelivery' | 'addOrderModalSchema' | 'none' ,
modalType?: 'productByDefault' | 'productByMember' | 'memberByDefault' | 'inquiryByDefault' | 'demandByDefault' | 'enquiryModel' | 'MergeOrderByDefault' | 'goodsModalSchema' | 'demandNumberSchema' | 'logisticsDelivery' | 'addOrderModalSchema' | 'selectGoodsSchema' | 'none' ,
useNestTable?: boolean, // 是否使用嵌套表格
nestColumns?: any[],
nestTableProps?: any,
......@@ -82,6 +82,9 @@ const ModalTable:React.FC<ModalTableProps> = (props) => {
case 'addOrderModalSchema': {
return addOrderModalSchema
}
case 'selectGoodsSchema': {
return logisticsSelectGoodsSearchSchema
}
case 'none': {
return {}
}
......
......@@ -673,3 +673,64 @@ export const logisticsDeliverySearchSchema: ISchema = {
}
}
}
export const logisticsSelectGoodsSearchSchema: ISchema = {
type: 'object',
properties: {
productName: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '商品名称',
align: 'flex-left',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
style: {
marginRight: 0
}
},
colStyle: {
marginTop: 20,
},
},
properties: {
brand: {
type: 'string',
"x-component-props": {
placeholder: '商品品牌',
style: {
width: 160
}
}
},
category: {
type: 'string',
"x-component": 'SearchSelect',
'x-component-props': {
placeholder: '商品品类',
fetchSearch: PublicApi.getWarehouseInvoicesTypeAll,
style: {
width: 160
}
},
},
submit: {
"x-component": 'Submit',
"x-mega-props": {
span: 1
},
"x-component-props": {
children: '查询'
}
}
}
}
}
}
import { ColumnType } from 'antd/lib/table/interface';
export const SelectGoodsColumns: ColumnType<any>[] = [
{
title: '商品ID',
key: 'productId',
dataIndex: 'productId',
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName',
},
{
title: '品类',
key: 'category',
dataIndex: 'category',
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand',
}
]
.revise_style {
:global {
.ant-form-item-label {
width: 174px;
label {
color:#6B778C
}
}
.ant-form-item-control {
width: 500px;
.ant-form-item-control-input-content {
position: relative;
.ant-btn-link {
position: absolute;
right: -120px;
}
.ant-picker {
width: 100%;
}
}
.ant-input-group-addon {
.ant-input-search-button {
background-color: #6B778C;
border-color: #6B778C;
}
}
}
.ant-radio-group-solid {
.ant-radio-button-wrapper-checked {
background: #6B778C;
border-color: #6B778C;
&:hover {
background: #6B778C;
border-color: #6B778C;
}
}
}
}
.upload_item {
padding: 5px 8px;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FAFBFC;
.upload_left {
display: flex;
align-items: center;
color: #303133;
:global {
.anticon-file-word {
color: #4279df;
font-size: 20px;
margin-right: 8px;
}
}
}
.upload_right {
color: #00B37A;
cursor: pointer;
:global {
.anticon-delete {
margin-left: 19px;
color: #C0C4CC;
}
}
}
}
}
\ No newline at end of file
import React, { useState, useEffect, useRef } from 'react';
import { history } from 'umi';
import styles from './index.less';
import ReturnEle from '@/components/ReturnEle';
import { ColumnType } from 'antd/lib/table/interface';
import { Tabs, Button, Card, Form, Input, Select, Table, Row, Col, Statistic } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { LinkOutlined, PlusOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
import ModalTable from '@/components/ModalTable';
import { SelectGoodsColumns } from './columns';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable'
const { TabPane } = Tabs;
const { Search } = Input;
const { Option } = Select;
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
};
/**
* @id: 订单id
* @shipmentOrderCode: 对应发货单号
* @relevanceOrderCode: 对应订单号/售后单
* @relevanceType: 1-销售订单 2-换货申请单(退货发货) 3-换货申请单(换货发货) 4-退货申请单 -> (自新建的时候才有这个)
* @createType: 1. 销售发货订单创建, 2. 生产通知订单创建, 3. 换货申请创建, 4.换货处理创建 , 5.退货申请创建,-> (默认没有为自新建)
* ps: 列表得返回这个物流的是哪个createType的,才能进行对象的接口请求
*/
const AddLogistics: React.FC<{}> = () => {
const ref = useRef<any>();
const { id, shipmentOrderCode, relevanceOrderCode, relevanceType, createType } = history.location.query;
const [data, setdata] = useState<any>([]); //表格列表数据
const [query, setQuery] = useState<any>({}); //表提交的数据
const [visible, setvisible] = useState<boolean>(false);
const [goodsRowSelection, goodsRowCtl] = useRowSelectionTable({ customKey: 'productId' })
const [listShipperAddress, setListShipperAddress] = useState<any>([]); //发货地址
const [listMemberCompany, setListMemberCompany] = useState<any>([]); //物流服务商
const [form] = Form.useForm();
/**输入框输入 */
const inputOnchange = (id, e, name) => {
const { value } = e.target
data.forEach(v => {
if (v.productId === id) {
v[name] = value
}
})
setdata([...data])
countTotal(name)
}
/** 计算总数 */
const countTotal = (name?: string) => {
let num: any = 0
data.forEach((item: any, idx: number) => {
if (name === 'carton') {
num += item.carton ? Number(item.carton) : 0
} else if (name === 'weight') {
num += item.weight ? Number(item.weight) : 0
} else if (name === 'volume') {
num += item.volume ? Number(item.volume) : 0
}
})
return num
}
/**表头 */
const columns: ColumnType<any>[] = [
{
title: 'ID',
key: 'productId',
dataIndex: 'productId'
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'categoryName',
dataIndex: 'categoryName'
},
{
title: '品牌',
key: 'brandName',
dataIndex: 'brandName'
},
{
title: '单位',
key: 'unitName',
dataIndex: 'unitName'
},
{
title: '数量',
key: 'amount',
width: 120,
dataIndex: 'amount',
render: (text: any, record: any, index: number) =>
<Form.Item noStyle name={`amount${index}`} initialValue={record.amount} rules={[{ required: true, message: '请输入数量' }]}>
<Input type='number' min={1} onBlur={(e) => inputOnchange(record.productId, e, 'amount')} />
</Form.Item>
},
{
title: '箱数',
key: 'carton',
width: 120,
dataIndex: 'carton',
render: (text: any, record: any, index: number) =>
<Form.Item noStyle name={`carton${index}`} initialValue={record.carton} rules={[{ required: true, message: '请输入箱数' }]}>
<Input type='number' min={1} onBlur={(e) => inputOnchange(record.productId, e, 'carton')} />
</Form.Item>
},
{
title: '重量 (KG)',
key: 'weight',
width: 120,
dataIndex: 'weight',
render: (text: any, record: any, index: number) =>
<Form.Item noStyle name={`weight${index}`} initialValue={record.weight} rules={[{ required: true, message: '请输入重量 (KG)' }]}>
<Input type='number' min={1} onBlur={(e) => inputOnchange(record.productId, e, 'weight')} />
</Form.Item>
},
{
title: '体积 (M3)',
key: 'volume',
width: 120,
dataIndex: 'volume',
render: (text: any, record: any, index: number) =>
<Form.Item noStyle name={`volume${index}`} initialValue={record.volume} rules={[{ required: true, message: '请输入体积 (M3)' }]}>
<Input type='number' min={1} onBlur={(e) => inputOnchange(record.productId, e, 'volume')} />
</Form.Item>
},
{
title: '操作',
key: 'options',
dataIndex: 'options',
render: (text: any, record: any, index: number) => <Button type='link' onClick={() => onHandleDelect(index)}>删除</Button>
}
]
/**接口请求 */
useEffect(() => {
/** 物流服务商*/
new Promise(resolve => {
PublicApi.getLogisticsSelectListMemberCompany().then(res => {
if (res.code === 1000) {
resolve(res.data)
}
})
}).then(res => {
setListMemberCompany(res)
}).catch(error => console.log(error));
/** 发货地址*/
new Promise(resolve => {
PublicApi.getLogisticsSelectListShipperAddress().then(res => {
if (res.code === 1000) {
resolve(res.data)
}
})
}).then(res => {
setListShipperAddress(res)
}).catch(error => console.log(error));
switch (Number(createType)) {
case 1:
PublicApi.getWarehouseInvoicesDetails({ invoicesId: id }).then((res: any) => {
if (res.code === 1000) {
const obj = {
receiverName: res.data.receiverName,
receiverPhone: res.data.phone,
receiverFullAddress: res.data.fullAddress,
shipmentOrderCode: res.data.invoicesNo,
relevanceOrderCode: res.data.orderNo,
voucherTime: res.data.transactionTime,
externalState: res.data.state
}
form.setFieldsValue(obj);
setQuery({ ...obj })
}
})
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
PublicApi.getAsReturnGoodsPageDetailByLogistics({ returnId: id }).then((res: any) => {
if (res.code === 1000) {
const obj = {
receiverName: res.data.receiveUserName,
receiverPhone: res.data.receiveUserTel,
receiverFullAddress: res.data.receiveAddress,
relevanceOrderCode: res.data.applyNo,
voucherTime: res.data.applyTime,
externalState: res.data.state,
digest: res.data.applyAbstract
}
form.setFieldsValue(obj);
setQuery({ ...obj })
}
})
break;
}
}, [])
/** 选择物流服务伤 */
const handleSelectCompany = (option: any) => {
const obj = { ...query }
obj.companyId = option.value
obj.companyName = option.children
setQuery(obj)
}
/**选择发货方地址 */
const handleSelectAddress = (option: any) => {
const obj = { ...query };
obj.shipperAddressId = option.value;
obj.shipperFullAddress = option.children;
setQuery(obj)
}
/**选择商品列表请求 */
const fetchData = (params?: any) => {
return new Promise(resolve => {
switch (Number(createType)) {
case 1:
PublicApi.getWarehouseInvoicesProductList({...params, invoicesId: id}).then(res => {
if(res.code === 1000) {
resolve(res.data)
}
})
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
PublicApi.getAsReturnGoodsPageCommodityByLogistics({...params, dataId: id}).then(res => {
if(res.code === 1000) {
resolve(res.data)
}
})
break;
}
})
}
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReturnEle description='返回' />}
extra={<Button type="primary"> 保存</Button>}
>
<Card>
<Tabs type="card">
{/** 基本信息 */}
<TabPane key='tab-1' tab='基本信息' forceRender>
<Form
{...layout}
form={form}
className={styles.revise_style}
>
<Form.Item label="单据摘要" name="digest" rules={[{ required: true, message: '请输入单据摘要' }]}>
<Input />
</Form.Item>
<Form.Item label="物流服务商" name="companyId" rules={[{ required: true, message: '请选择流服务商' }]}>
<Select allowClear onChange={(value, option) => handleSelectCompany(option)}>
{
listMemberCompany.map((item: any, idx: number) => (
<Option roleid={item.roleId} memberid={item.memberId} key={item.id} value={item.id}>{item.name}</Option>
))
}
</Select>
</Form.Item>
<Form.Item label="物流单号" name='receiverName1'><span></span></Form.Item>
<Form.Item label='对应发货单号' name='shipmentOrderCode'>
<Search disabled={createType} readOnly value={Object.keys(query).length > 0 ? query.shipmentOrderCode : undefined} enterButton={<><LinkOutlined /> 选择</>} />
<Button type='link'>查看单号详情</Button>
</Form.Item>
<Form.Item label='对应订单号/售后单' name='relevanceOrderCode'>
<Search disabled={createType} readOnly value={Object.keys(query).length > 0 ? query.relevanceOrderCode : undefined} enterButton={<><LinkOutlined /> 选择</>} />
<Button type='link'>查看单号详情</Button>
</Form.Item>
<Form.Item label="收货方" name='receiverName'><span>{query.receiverName}/{query.receiverPhone}</span></Form.Item>
<Form.Item label="收货地址" name='receiverFullAddress'>
<div>{query.receiverFullAddress}</div>
</Form.Item>
<Form.Item label="发货地址" name="shipperAddressId" rules={[{ required: true, message: '请选择发货地址' }]}>
<Select allowClear onChange={(value, option) => handleSelectAddress(option)}>
{
listShipperAddress.map((item: any, idx: number) => (
<Option key={item.id} value={item.id}>{item.fullAddress}</Option>
))
}
</Select>
</Form.Item>
<Form.Item label="单据时间" name='voucherTime'><span>{query.voucherTime}</span></Form.Item>
<Form.Item label="外部状态" name='externalState'><span>{query.externalState}</span></Form.Item>
</Form>
</TabPane>
{/** 物流单明细 */}
<TabPane key='tab-2' tab='物流单明细' forceRender>
<Button block type='dashed' style={{ marginBottom: '24px' }} onClick={() => setvisible(true)}><PlusOutlined />选择商品</Button>
<Form form={form}>
<Table columns={columns} dataSource={data} rowKey={'productId'} pagination={false} />
</Form>
<Row gutter={[24, 24]} style={{ margin: '0 0 0 65%', width: '35%' }}>
<Col span={8}><Statistic title="总箱数(箱)" value={countTotal('carton')} /></Col>
<Col span={8}><Statistic title="总重量(KG)" value={countTotal('weight')} /></Col>
<Col span={8}><Statistic title="总体积(M3)" value={countTotal('volume')} /></Col>
</Row>
</TabPane>
{/** 运费 */}
<TabPane key='tab-3' tab='运费' forceRender>
<Form {...layout}>
<Form.Item label='运费'>
<span></span>
</Form.Item>
<Form.Item label='结算方式'>
<span></span>
</Form.Item>
</Form>
</TabPane>
{/** 流转记录 */}
<TabPane key='tab-4' tab='流转记录' forceRender></TabPane>
</Tabs>
</Card>
<ModalTable
modalTitle='选择商品'
visible={visible}
columns={SelectGoodsColumns}
fetchTableData={(params) => fetchData(params)}
cancel={() => setvisible(false)}
rowSelection={goodsRowSelection}
modalType='selectGoodsSchema'
searchName='productName'
tableProps={{
rowKey: 'productId'
}}
/>
</PageHeaderWrapper>
)
}
export default AddLogistics;
......@@ -25,13 +25,13 @@ const Category: React.FC<CategoryPropsType> = (props) => {
useEffect(() => {
let getCategoryFn
let params: any = {}
const params: any = {}
let headers = {}
switch (type) {
case LAYOUT_TYPE.mall:
if (mallTemplateId) {
params.templateId = mallTemplateId
getCategoryFn = PublicApi.getTemplatePlatformFindAllCategoryTree
getCategoryFn = PublicApi.getTemplateWebCategoryWebFindEnterpriseCategoryTree
fetchCategoryList(getCategoryFn, params, type)
}
break
......
......@@ -4,8 +4,10 @@
margin: 0 auto;
z-index: 9;
.anchor {
position: absolute;
overflow: hidden;
top: 20px;
width: 88px;
left: -128px;
......
import React, { useState, useEffect } from 'react';
import { UPLOAD_TYPE } from '@/constants'
import { Modal, Anchor, Layout, Menu, Form, Divider, Input, Button, Upload, Select, AutoComplete, Cascader, Spin, InputNumber } from 'antd';
import { Modal, Anchor, Layout, Menu, Form, Divider, Input, Button, Upload, Select, AutoComplete, Cascader, Spin, InputNumber, message } from 'antd';
import style from '../index.less';
import { UploadFile } from 'antd/lib/upload/interface';
import { LinkOutlined, DeleteOutlined, UploadOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
......@@ -140,6 +141,42 @@ const ModalAnchor: React.FC<anchorParams> = (props) => {
setattribute([...attribute])
}
// 删除附件
const removeFiles = (index: any) => {
const arr = [...files];
arr.splice(index, 1);
setFiles(arr);
}
useEffect(() => {
if (Object.keys(fetchdata).length > 0) {
setFiles(fetchdata.urls)
}
}, [fetchdata])
/**判断文件类型和大小 */
const beforeDocUpload = (file: UploadFile) => {
const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) {
message.error('上传文件大小不超过 20M!');
}
return isLt20M;
}
// 上传回调
const handleChange = ({ file }) => {
const arr: any = files;
setloading(true);
if (file.response) {
if (file.response.code === 1000) {
arr.push({
name: file.name,
url: file.response.data
})
setloading(false);
}
}
setFiles([...arr])
}
return (
<Modal
title='通过平台属性添加'
......@@ -236,7 +273,7 @@ const ModalAnchor: React.FC<anchorParams> = (props) => {
<LinkOutlined />
<span>{v.name}</span>
</div>
<div className={style.upload_right}>
<div className={style.upload_right} onClick={() => removeFiles(index)}>
<DeleteOutlined />
</div>
</div>
......@@ -249,6 +286,8 @@ const ModalAnchor: React.FC<anchorParams> = (props) => {
data={{ fileType: UPLOAD_TYPE }}
showUploadList={false}
accept='.doc,.docx,.pdf,.ppt,.pptx,.xls,.xlsx'
beforeUpload={beforeDocUpload}
onChange={handleChange}
>
<Button loading={loading} icon={<UploadOutlined />}>上传文件</Button>
<div style={{ marginTop: '8px' }}>一次上传一个文件,每个附件大小不能超过 20M</div>
......
......@@ -434,7 +434,7 @@ const Details: React.FC<parmas> = (props) => {
{
Object.keys(data).length > 0 &&
<>
{type !== 'quote' ?
{type === 'rfq' ?
<TabPane tab="外部流转" key="1">
<Steps
style={{ padding: '20px 0' }}
......@@ -578,7 +578,7 @@ const Details: React.FC<parmas> = (props) => {
</div>
<div className={style.item_wrap}>
{
type !== 'quote' ?
type === 'rfq' ?
<>
<div className={style.mainCol_title}>外部流转记录</div>
<Table columns={flowRecord.external} rowKey='id' pagination={false} dataSource={data.externalInquiryListLogResponses} />
......
......@@ -28,7 +28,7 @@ class SiteStore implements ISiteModule {
siteId: this.siteId
}
const res = await PublicApi.getTemplatePlatformFindUseTemplateBySite(param)
const res = await PublicApi.getTemplateWebPageTemplateWebFindEnterpriseTemplate(param)
runInAction(() => {
this.mallTemplateInfo = res.data || {}
this.mallTemplateId = this.mallTemplateInfo.id
......
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