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

feat(商品询价): 二次询价

parent 3d23566e
......@@ -50,6 +50,7 @@ const ModalLayout: React.FC<ModalProps> = ({
const [form] = Form.useForm();
const [channel, setChannel] = useState<channel>([])
const handleChannelFind = useCallback(async () => {
await PublicApi.getOrderMemberPaymentParameterChannelFind({ payChannel }).then(res => {
if (res.code !== 1000) {
......@@ -92,7 +93,7 @@ const ModalLayout: React.FC<ModalProps> = ({
return (
<Modal
width={576}
title='新增参数配置'
title='参数配置'
visible={visible}
onOk={handleConfirm}
onCancel={handleCancel}
......
import React, { useState, ReactNode, useEffect } from 'react';
import { Input } from 'antd';
interface NumberInputProps {
/** 带标签的 input,设置后置标签 */
addonAfter?: ReactNode,
/** 带标签的 input,设置前置标签 */
addonBefore?: ReactNode,
/** 回显数据 */
fieldValue?: string,
/** 输入框内容变化时的回调 */
onChange?: Function,
/** 正则表达式 */
pattern?: RegExp,
}
const NumericInput = props => {
const { value, onChange, addonAfter, addonBefore, pattern } = props;
const handleChange = e => {
const { value } = e.target;
// const reg = /^(\-)?\d+(\.(\d){0,2})?$/;
const reg = pattern;
if (
(!isNaN(value) && reg.test(value)) ||
value === '' ||
value === '-'
) {
onChange(value);
}
};
const handleBulur = () => {
let valueTemp = value;
if (value.charAt(value.length - 1) === '.' || value === '-') {
valueTemp = value.slice(0, -1);
}
onChange(valueTemp.replace(/0*(\d+)/, '$1'));
};
return <Input value={value} onChange={handleChange} onBlur={handleBulur} addonAfter={addonAfter} addonBefore={addonBefore} />;
};
const NumberInput: React.FC<NumberInputProps> = (props) => {
const { fieldValue, onChange, addonAfter, addonBefore, pattern } = props;
const [value, setValue] = useState('');
const handleChange = e => {
setValue(e);
onChange(e);
};
useEffect(() => {
if (fieldValue) {
setValue(fieldValue)
}
}, [fieldValue])
return <NumericInput value={value} onChange={handleChange} addonAfter={addonAfter} addonBefore={addonBefore} pattern={pattern} />;
};
export default NumberInput
......@@ -14,6 +14,7 @@ import wechat from '@/assets/icons/wechat_icon.png';
import unionpay from '@/assets/icons/unionpay_icon.png';
import balance from '@/assets/icons/balance_icon.png';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NumberInput from './components/number';
const PIC_MAP = {
1: alipay,
......@@ -142,6 +143,7 @@ const PaySettingLayout = () => {
}
params.push(_obj);
})
setPayChannel(data[0].channels[0].payChannel)
setChannel(_channel)
setParameters(params);
setParameterFind(data);
......@@ -248,6 +250,16 @@ const PaySettingLayout = () => {
return [..._parameters]
}
const handleInputChange = (e, code, payType, _index) => {
const _parameters = [...parameters];
_parameters.forEach(item => {
if (item.payType === payType) {
item.channels[0].parameters[_index] = { code, value: e, remark: '' }
}
})
setParameters(_parameters)
}
return (
<>
<PeripheralLayout
......@@ -276,7 +288,7 @@ const PaySettingLayout = () => {
>
<div className={style.tabsLayout}>
{item.payType === 1 && (
<Tabs>
<Tabs onChange={(key) => setPayChannel(key)}>
{item.channels.map((_item, _index) => (
<TabPane tab={<Space><Image preview={false} width={16} height={16} src={PIC_MAP[_item.payChannel]} />{_item.payChannelName}</Space>} key={_item.payChannel} forceRender>
<Form.Item
......@@ -375,18 +387,33 @@ const PaySettingLayout = () => {
shouldUpdate={(prevValues, currentValues) => prevValues[`payChannel_${_item.payChannel}`] !== currentValues[`payChannel_${_item.payChannel}`]}
>
{({ getFieldValue }) => (
getFieldValue(`payChannel_${_item.payChannel}`) === 6 ) && (
getFieldValue(`payChannel_${_item.payChannel}`) === 6) && (
<Fragment>
<Form.Item
label='授信额度设置'
>
<Space direction='vertical' style={{ width: '100%' }}>
初始申请额度不超过:
<Input type='number' addonAfter='人民币' />
<NumberInput
onChange={(e) => handleInputChange(e, 30, item.payType, 0)}
addonAfter='人民币'
pattern={/^(\-)?\d+(\.(\d){0,2})?$/}
fieldValue={_item.parameters[0]?.value}
/>
允许满:
<Input type='number' addonAfter='天' />
<NumberInput
onChange={(e) => handleInputChange(e, 31, item.payType, 1)}
addonAfter='天'
pattern={/^[1-9]\d*$/}
fieldValue={_item.parameters[1]?.value}
/>
申请上调:
<Input type='number' addonAfter='%' />
<NumberInput
onChange={(e) => handleInputChange(e, 32, item.payType, 2)}
addonAfter='%'
pattern={/^-?\d*(\.\d*)?$/}
fieldValue={_item.parameters[2]?.value}
/>
</Space>
</Form.Item>
</Fragment>
......
import React, { useCallback, useState } from 'react';
import { Modal, Form, Radio, Tooltip, Typography, Input, Space } from 'antd';
import { PublicApi } from '@/services/api';
interface AutditLayoutProps {
/** 显示/隐藏 */
visible?: boolean,
/** 关闭 */
onCancel?: Function,
/** 确定 */
onOk?: Function,
id: number,
}
const AuditLayout: React.FC<AutditLayoutProps> = (props: any) => {
const { visible, onCancel, onOk, id } = props;
const [form] = Form.useForm();
const [loading, setLoading] = useState<boolean>(false);
const handleSubmit = useCallback(async () => {
await form.validateFields().then(res => {
PublicApi.postTransactionNotarizeEnquiryQuotedPriceAffirm({ id, state: res.state, audit: res.audit }).then(res => {
if (res.code !== 1000) {
setLoading(false)
return
}
onOk();
})
})
}, [id])
return (
<Modal
width={600}
title='单据审核'
visible={visible}
onCancel={onCancel}
confirmLoading={loading}
onOk={handleSubmit}
>
<Form layout='vertical' form={form}>
<Form.Item
name='state'
initialValue={1}
>
<Radio.Group>
<Tooltip
placement="topLeft"
title={
<Space direction='vertical'>
<Typography.Text style={{ color: '#FFF' }}>1.报价单查询列表,直接创建采购订单</Typography.Text>
<Typography.Text style={{ color: '#FFF' }}>2.新增采购订单,选择接受的报价单</Typography.Text>
</Space>
}
>
<Radio value={1}>接受报价</Radio>
</Tooltip>
<Tooltip
placement="topLeft"
title={
<Space direction='vertical'>
<Typography.Text style={{ color: '#FFF' }}>1.不接受会员报价,必填不接受原因</Typography.Text>
<Typography.Text style={{ color: '#FFF' }}>2.不接受报价后,报价会员可再次报价</Typography.Text>
</Space>
}
>
<Radio value={0}>不接受报价</Radio>
</Tooltip>
</Radio.Group>
</Form.Item>
<Form.Item
shouldUpdate={(prevValues, curValues) => prevValues.state !== curValues.state}
>
{({ getFieldValue }) => getFieldValue('state') !== 1 && (
<Form.Item
label='不接受报价原因'
name='audit'
rules={[{ required: true, message: '请输入不接受报价原因' }]}
>
<Input.TextArea maxLength={100} rows={2} />
</Form.Item>
)}
</Form.Item>
</Form>
</Modal>
)
}
export default AuditLayout;
......@@ -15,6 +15,7 @@ import GeneralLayout from '@/pages/transaction/components/detailLayout/component
import RecordLyout from '@/pages/transaction/components/detailLayout/components/recordLyout';
import ModalOperate from '@/pages/transaction/components/modalOperate';
import { ENTERPRISE_CENTER_URL } from '@/constants';
import AuditLayout from './audit';
const TABLINK = [
{ id: 'progressLayout', title: '流转进度' },
......@@ -63,6 +64,8 @@ const ConfirmOfferDetail = () => {
{
col: [
{ label: '单据时间', extra: format(data.voucherTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
])
......@@ -205,9 +208,6 @@ const ConfirmOfferDetail = () => {
case 'waitAuditInquiryTwo':
fetchSoure = PublicApi.postTransactionNotarizeEnquiryQuotedPriceAuditTwo
break;
case 'waitSubmitOffer':
fetchSoure = PublicApi.postTransactionNotarizeEnquiryQuotedPriceAffirm
break;
}
return fetchSoure
}
......@@ -257,15 +257,23 @@ const ConfirmOfferDetail = () => {
</Fragment>
}
/>
<ModalOperate
id={id}
title="单据审核"
modalType="audit"
visible={visible}
fetch={fetchLink()}
onCancel={() => setVisible(false)}
onOk={() => history.goBack()}
/>
{pathPci === 'waitSubmitOffer' ?
<AuditLayout
id={id}
visible={visible}
onCancel={() => setVisible(false)}
onOk={() => history.goBack()}
/> :
<ModalOperate
id={id}
title="单据审核"
modalType="audit"
visible={visible}
fetch={fetchLink()}
onCancel={() => setVisible(false)}
onOk={() => history.goBack()}
/>}
</Context.Provider>
)
}
......
......@@ -71,6 +71,8 @@ const ConfirmOfferPreview = () => {
{ label: '交付日期', extra: format(data.deliveryTime) },
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
{
......
......@@ -80,7 +80,7 @@ const WaitSubmitOffer = () => {
title: '操作',
key: 'options',
dataIndex: 'options',
render: (text: any, record: any) => <Button type='link' onClick={() => history.push(`/memberCenter/tranactionAbility/confirmOffer/waitSubmitOffer/offer/detail?id=${record.id}`)}>提交报价单</Button>
render: (text: any, record: any) => <Button type='link' onClick={() => history.push(`/memberCenter/tranactionAbility/confirmOffer/waitSubmitOffer/offer/detail?id=${record.id}`)}>确认报价单</Button>
}
]
......
import React, { Fragment, useEffect, useState } from 'react';
import { Button, Tag, Badge, Typography, Space } from 'antd';
import React, { Fragment, useCallback, useEffect, useState } from 'react';
import { Button, Tag, Badge, Typography, Space, Drawer } from 'antd';
import { history } from 'umi';
import { ColumnType } from 'antd/lib/table/interface';
import PeripheralLayout from '@/pages/transaction/components/detailLayout';
......@@ -15,6 +15,7 @@ import ListLayout from '@/pages/transaction/components/detailLayout/components/l
import GeneralLayout from '@/pages/transaction/components/detailLayout/components/generalLayout';
import RecordLyout from '@/pages/transaction/components/detailLayout/components/recordLyout';
import ModalOperate from '@/pages/transaction/components/modalOperate';
import { StandardTable } from 'god';
const TABLINK = [
{ id: 'progressLayout', title: '流转进度' },
......@@ -42,6 +43,8 @@ const InquiryOfferDetail = () => {
const [otherEffect, setOtherEffect] = useState<any>([]);
const [fileEffect, setFileEffect] = useState<any>([]);
const [visible, setVisible] = useState<boolean>(false);
const [commoditySkuId, setCommoditySkuId] = useState();
const [historyVisible, setHistoryVisible] = useState<boolean>(false);
const handleBasicEffect = (data: any) => {
setBasicEffect([
......@@ -87,6 +90,8 @@ const InquiryOfferDetail = () => {
{
col: [
{ label: '其他说明', extra: data.otherRequire },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
])
......@@ -192,8 +197,89 @@ const InquiryOfferDetail = () => {
dataIndex: 'money',
render: money => <>{money ? `¥${money.toFixed(2)}` : '¥0.00'}</>
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
render: (_text, _data, index) => (
<Button type="link" onClick={() => handleHitory(_data)}>历史报价</Button>
)
},
]
const hitoryColumns: ColumnType<any>[] = [
{
title: '商品ID',
key: 'productId',
dataIndex: 'productId'
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '采购数量',
key: 'purchaseCount',
dataIndex: 'purchaseCount'
},
{
title: '报价单价',
key: 'price',
dataIndex: 'price'
},
{
title: '询价会员',
key: 'memberName',
dataIndex: 'memberName'
},
{
title: '报价会员',
key: 'quoteMemberName',
dataIndex: 'quoteMemberName'
},
{
title: '报价时间',
key: 'createTime',
dataIndex: 'createTime'
},
{
title: '报价单',
key: 'quotationNo',
dataIndex: 'quotationNo'
},
{
title: '外部状态',
key: 'externalStateName',
dataIndex: 'externalStateName'
},
{
title: '内部状态',
key: 'interiorStateName',
dataIndex: 'interiorStateName'
},
]
const handleHitory = (_data) => {
setCommoditySkuId(_data.productId);
setHistoryVisible(true)
}
const fetchLink = () => {
let fetchSoure: any = null;
switch (pathPci) {
......@@ -207,6 +293,17 @@ const InquiryOfferDetail = () => {
return fetchSoure
}
const fetchTableData = useCallback((params: any) => {
return new Promise(resolve => {
PublicApi.getTransactionProductQuotationHistoryList({ ...params, commoditySkuId }).then(res => {
if (res.code !== 1000) {
return
}
resolve(res.data);
})
})
}, [commoditySkuId])
return (
<Context.Provider value={dataSource}>
<PeripheralLayout
......@@ -261,6 +358,20 @@ const InquiryOfferDetail = () => {
onCancel={() => setVisible(false)}
onOk={() => history.goBack()}
/>
<Drawer
width={1200}
title='历史报价'
visible={historyVisible}
onClose={() => setVisible(false)}
>
<StandardTable
columns={hitoryColumns}
tableProps={{ rowKey: 'productId' }}
fetchTableData={fetchTableData}
/>
</Drawer>
</Context.Provider>
)
}
......
......@@ -71,6 +71,8 @@ const InquiryOfferPreview = () => {
{ label: '交付日期', extra: format(data.deliveryTime) },
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
{
......
......@@ -118,6 +118,9 @@ const AddedFormLayout: React.FC<AddedFormLayoutProps> = (props: any) => {
enclosureUrls: res.enclosureUrls,
inquiryListProductRequests: res.inquiryListProductRequests,
inquiryListId: inquiry.inquiryListId || id,
contactName: res.contactName,
contactPhone: res.contactPhone,
phoneCode: res.phoneCode,
}
if (id && !spam) { params.id = id }
fetchRequest({ ...params }).then(res => {
......@@ -176,9 +179,9 @@ const AddedFormLayout: React.FC<AddedFormLayoutProps> = (props: any) => {
const getContacts = (value) => {
form.setFieldsValue({
"contacts": value.name,
'contactsPhone': value.phone,
'phoneCode': 86,
"contactName": value.name,
'contactPhone': value.phone,
'phoneCode': value.phoneCode,
});
}
......
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { Row, Col, Form, Input, InputNumber, Select, Button } from 'antd';
import Card from '@/pages/transaction/components/card';
import { LinkOutlined } from '@ant-design/icons';
......@@ -14,7 +14,8 @@ interface OtherExplainLayoutProps {
const OtherExplainLayout: React.FC<OtherExplainLayoutProps> = (props: any) => {
const { getContacts } = props;
const [visible, setVisible] = useState<boolean>(false)
const [visible, setVisible] = useState<boolean>(false);
const [telCode, setTelCode] = useState<any>([]);
const handleFetchData = useCallback((params: any) => {
return new Promise(resolve => {
PublicApi.getMemberManageUsersPage({ ...params }).then(res => {
......@@ -28,6 +29,14 @@ const OtherExplainLayout: React.FC<OtherExplainLayoutProps> = (props: any) => {
})
}, [])
const fetchTelCode = async () => {
const { data, code } = await PublicApi.getManageCountryAreaGetTelCode();
if (code !== 1000) {
return;
}
setTelCode(data)
};
const toggle = (flag: boolean) => {
setVisible(flag)
}
......@@ -55,6 +64,10 @@ const OtherExplainLayout: React.FC<OtherExplainLayoutProps> = (props: any) => {
},
]
useEffect(() => {
fetchTelCode()
}, [])
const handleConfirm = (selectRowKeys: string[] | number[], selectRowRecord: any) => {
const target = selectRowRecord[0];
getContacts(target)
......@@ -98,7 +111,9 @@ const OtherExplainLayout: React.FC<OtherExplainLayoutProps> = (props: any) => {
rules={[{ required: true, message: '请选择' }]}
>
<Select>
<Select.Option value={86}>86</Select.Option>
{telCode.map(item => (
<Select.Option key={item} value={item}>{item}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
......
import React, { useEffect, useState } from 'react';
import { Form, Button, Table, Input, Image } from 'antd';
import React, { useCallback, useEffect, useState } from 'react';
import { Form, Button, Table, Input, Image, Drawer } from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
import Card from '@/pages/transaction/components/card';
import { isEmpty } from '@/components/NiceForm/components/AntUpload/shared';
import EyePreview from '@/components/EyePreview';
import { ENTERPRISE_CENTER_URL } from '@/constants';
import { PublicApi } from '@/services/api';
import { StandardTable } from 'god';
interface ProductQuoteLayoutProps {
/** 回显 */
......@@ -14,6 +16,8 @@ interface ProductQuoteLayoutProps {
const ProductQuoteLayout: React.FC<ProductQuoteLayoutProps> = (props: any) => {
const { setProductQuote } = props;
const [dataSource, setDataSource] = useState<any[]>([]);
const [commoditySkuId, setCommoditySkuId] = useState();
const [visible, setVisible] = useState<boolean>(false);
const count = (num: any, price: any) => {
let money: any = null;
money = (Number(price) * 1) * Number(num);
......@@ -101,11 +105,80 @@ const ProductQuoteLayout: React.FC<ProductQuoteLayoutProps> = (props: any) => {
key: "operate",
dataIndex: "operate",
render: (_text, _data, index) => (
<Button type="link">历史报价</Button>
<Button type="link" onClick={() => handleHitory(_data)}>历史报价</Button>
)
},
]
const hitoryColumns: ColumnType<any>[] = [
{
title: '商品ID',
key: 'productId',
dataIndex: 'productId'
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '采购数量',
key: 'purchaseCount',
dataIndex: 'purchaseCount'
},
{
title: '报价单价',
key: 'price',
dataIndex: 'price'
},
{
title: '询价会员',
key: 'memberName',
dataIndex: 'memberName'
},
{
title: '报价会员',
key: 'quoteMemberName',
dataIndex: 'quoteMemberName'
},
{
title: '报价时间',
key: 'createTime',
dataIndex: 'createTime'
},
{
title: '报价单',
key: 'quotationNo',
dataIndex: 'quotationNo'
},
{
title: '外部状态',
key: 'externalStateName',
dataIndex: 'externalStateName'
},
{
title: '内部状态',
key: 'interiorStateName',
dataIndex: 'interiorStateName'
},
]
useEffect(() => {
if (!isEmpty(setProductQuote)) {
console.log(setProductQuote)
......@@ -113,6 +186,22 @@ const ProductQuoteLayout: React.FC<ProductQuoteLayoutProps> = (props: any) => {
}
}, [setProductQuote])
const handleHitory = (_data) => {
setCommoditySkuId(_data.productId);
setVisible(true)
}
const fetchTableData = useCallback((params: any) => {
return new Promise(resolve => {
PublicApi.getTransactionProductQuotationHistoryList({ ...params, commoditySkuId }).then(res => {
if (res.code !== 1000) {
return
}
resolve(res.data);
})
})
}, [commoditySkuId])
return (
<Card
id="productQuoteLayout"
......@@ -128,6 +217,18 @@ const ProductQuoteLayout: React.FC<ProductQuoteLayoutProps> = (props: any) => {
dataSource={dataSource}
pagination={false}
/>
<Drawer
width={1200}
title='历史报价'
visible={visible}
onClose={() => setVisible(false)}
>
<StandardTable
columns={hitoryColumns}
tableProps={{ rowKey: 'productId' }}
fetchTableData={fetchTableData}
/>
</Drawer>
</Form.Item>
</Card>
)
......
......@@ -74,8 +74,8 @@ const ProductInquiryDetail = () => {
{ label: '交付日期', extra: format(data.deliveryTime) },
{ label: '交付地址', extra: data.fullAddress },
{ label: '报价截止时间', extra: format(data.quotationAsTime) },
{ label: '询价联系人', extra: data.contacts },
{ label: '联系人电话', extra: data.contactsPhone }
{ label: '询价联系人', extra: data.contactName },
{ label: '联系人电话', extra: data.contactPhone }
]
},
{
......
......@@ -212,8 +212,8 @@ const AddedFormLayout: React.FC<AddedFormLayoutProps> = (props: any) => {
category: item.customerCategoryName,
brand: item.brandName,
unit: item.unitName,
purchaseCount: 1,
logistics: '',
purchaseCount: item.purchaseCount,
logistics: item.logistics || {},
memberId: item.memberId,
memberRoleId: item.memberRoleId,
taxRate: item.taxRate,
......
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