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

🦄 refactor: 新增商品询价重构

parent af84ae3d
......@@ -42,6 +42,7 @@ export default [
path: '/memberCenter/tranactionAbility/productInquiry/waitAddInquiry/rfq',
name: '立即询价',
hideInMenu: true,
noMargin: true,
component: '@/pages/transaction/dealAbility/productInquiry/waitAddInquiry/rfq'
},
// 新建询价单
......@@ -49,6 +50,7 @@ export default [
path: '/memberCenter/tranactionAbility/productInquiry/waitAddInquiry/add',
name: '新建询价单',
hideInMenu: true,
noMargin: true,
component: '@/pages/transaction/dealAbility/productInquiry/waitAddInquiry/add'
},
// 编辑询价单
......@@ -56,6 +58,7 @@ export default [
path: '/memberCenter/tranactionAbility/productInquiry/waitAddInquiry/edit',
name: '编辑询价单',
hideInMenu: true,
noMargin: true,
component: '@/pages/transaction/dealAbility/productInquiry/waitAddInquiry/edit'
},
{
......
......@@ -69,15 +69,27 @@ const UploadFiles: React.FC<PickUploadProps> = (props: PickUploadProps) => {
// disabled: loading || disabled,
showUploadList: false,
onChange(info: UploadChangeParam) {
if(info.file.status === 'error' || (info.file.status === 'done' && info.file.response?.code !== 1000)) {
if (info.file.status === 'error' || (info.file.status === 'done' && info.file.response?.code !== 1000)) {
message.error(info.file.response?.message || "上传失败, 请检查上传接口");
}
// 如果不存在fileList, 只存在onChange 那么也要改变组件的file
if (!("fileList" in props)) {
setFiles(info.fileList);
const fileList = info.fileList;
const newList = fileList.map((file) => {
return {
name: file.name,
url: file.url || file.response?.data,
uid: file.uid,
status: file.status,
percent: file.percent,
size: file.size,
type: file.type,
}
if(onChange) {
})
setFiles(newList);
}
if (onChange) {
onChange(info)
}
......@@ -89,17 +101,17 @@ const UploadFiles: React.FC<PickUploadProps> = (props: PickUploadProps) => {
if (disable) {
return;
}
if(onRemove) {
if (onRemove) {
onRemove(fileItem);
}
if(!hasFileListProps) {
if (!hasFileListProps) {
const newFileList = files.filter((_item) => _item.url !== fileItem.url);
setFiles(newFileList);
}
}
const renderFileItem = () => {
return (
<div className={filesContainerCs} style={{order: 1}}>
<div className={filesContainerCs} style={{ order: 1 }}>
{
files.map((_item: UploadFile, key) => {
return (
......@@ -107,14 +119,14 @@ const UploadFiles: React.FC<PickUploadProps> = (props: PickUploadProps) => {
{
_item.status === 'uploading' && (
<div className={styles.uploadProgress}>
<Progress percent={_item.percent} status="active" size="small" showInfo={false}/>
<Progress percent={_item.percent} status="active" size="small" showInfo={false} />
</div>
)
}
<div className={styles.renderFileItem} >
<div className={styles['fileItem-left']}>
<img className={styles.img} src={pdf_icon} />
<a className={cx({[styles.error]: _item.status === 'error' || !_item.url})} href={_item.url} target="_blank">{_item.name}</a>
<a className={cx({ [styles.error]: _item.status === 'error' || !_item.url })} href={_item.url} target="_blank">{_item.name}</a>
</div>
{
!disable && (
......@@ -137,7 +149,7 @@ const UploadFiles: React.FC<PickUploadProps> = (props: PickUploadProps) => {
}
{
!disable && (
<div style={{order: uploadOrder}}>
<div style={{ order: uploadOrder }}>
<Upload {...uploadProps} >
{
children || (
......@@ -164,7 +176,7 @@ UploadFiles.defaultProps = {
action: '/api/file/file/upload',
headers: {},
beforeUpload: (file, fileList) => true,
onChange: (file: UploadChangeParam) => {},
onChange: (file: UploadChangeParam) => { },
customizeItemRender: null,
onRemove: null,
disable: false,
......
......@@ -14,7 +14,7 @@ const Card: React.FC<CardType> = (props: any) => {
<div id={id} className='ant-card ant-card-bordered' style={{ overflow: 'hidden' }}>
<div className='ant-card-head' style={{ padding: 0, backgroundColor: backgroundColor ? backgroundColor : 'transparent' }}>
<div className='ant-card-head-wrapper' style={{ padding: '12px 16px' }}>
<div className='ant-card-head-wrapper' style={{ color: backgroundColor ? '#FFF' : '#303133' }}>
<div className='ant-card-head-wrapper' style={{ color: backgroundColor ? '#FFF' : '#303133', fontWeight: 'bold' }}>
{title}
</div>
{extra &&
......
......@@ -3,7 +3,7 @@ import { Anchor } from 'antd';
import { Context } from './components/context';
import style from './index.less';
import { ArrowLeftOutlined } from '@ant-design/icons';
import {history} from 'umi';
import { history } from 'umi';
const activeAnchorClassName = 'ant-anchor-link-active'
......@@ -14,7 +14,7 @@ export type tabLink = {
export interface IProps {
/** 单号 */
no?: string,
no?: string | React.ReactNode,
/** 详情描述 */
detail?: string,
/** 锚点Link */
......@@ -23,6 +23,8 @@ export interface IProps {
effect?: React.ReactNode,
/** 页面的组件 */
components?: React.ReactNode,
/** 隐藏头部分割线 */
hideBreak?: boolean,
}
const PeripheralLayout: React.FC<IProps> = (props: any) => {
......@@ -32,6 +34,7 @@ const PeripheralLayout: React.FC<IProps> = (props: any) => {
tabLink,
effect,
components,
hideBreak
} = props;
const dataSource = useContext(Context)
......@@ -71,7 +74,7 @@ const PeripheralLayout: React.FC<IProps> = (props: any) => {
<ArrowLeftOutlined className={style.goBack} onClick={() => history.goBack()} />
<span className={style.titleContext}>
{detail ? detail : dataSource.details}
&nbsp;|&nbsp;
&nbsp;{!hideBreak && '|'}&nbsp;
{no}
</span>
</div>
......
import React from 'react';
import AddForm from './addForm';
import { history } from 'umi';
const AddEnquiryOrder:React.FC<{}> = () => {
import { PublicApi } from '@/services/api';
const AddEnquiryOrder = (props: any) => {
return(
<AddForm
type={1}
title={props.route.name}
fetchRequest={PublicApi.postTransactionInquiryListAdd}
/>
)
}
......
import React from 'react';
import { Form, Row, Col } from 'antd';
import Card from '@/pages/transaction/components/card';
import UploadFiles from '@/components/UploadFiles/UploadFiles';
const AttachLayout = () => {
const customizeItemRender = (file) => {
console.log(file)
}
return (
<Card
id="attachLayout"
title="附件"
>
<Row gutter={[48, 24]}>
<Col span={12}>
<Form.Item label="附件" name="enclosureUrls">
<UploadFiles beforeUpload={customizeItemRender} />
</Form.Item>
</Col>
</Row>
</Card>
)
}
export default AttachLayout;
import React, { useState, useEffect } from 'react';
import { Form, Button, Upload, message } from 'antd';
import { UPLOAD_TYPE } from '@/constants'
import { UploadFile, UploadChangeParam } from 'antd/lib/upload/interface';
import styles from './index.less';
import { UploadOutlined, DeleteOutlined, LinkOutlined } from '@ant-design/icons';
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
};
export interface parmas {
handleGetEnclosureUrls?: Function,
editData?: any
}
const Attached: React.FC<parmas> = (props) => {
const { handleGetEnclosureUrls, editData } = props;
const [files, setFiles] = useState([]);
const [loading, setloading] = useState(false);
/**判断文件类型和大小 */
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])
handleGetEnclosureUrls(arr);
}
// 删除附件
const removeFiles = (index: any) => {
const arr = [...files];
arr.splice(index, 1);
setFiles(arr);
handleGetEnclosureUrls(arr);
}
useEffect(() => {
if (Object.keys(editData).length > 0) {
setFiles(editData.enclosureUrls)
}
}, [editData])
return (
<Form
{...layout}
className={styles.revise_style}
>
<Form.Item label='附件' name='upload'>
<div className={styles.upload_data}>
{files.length > 0 && files.map((v, index) => (
<div key={index} className={styles.upload_item}>
<div className={styles.upload_left}>
<LinkOutlined />
<span>{v.name}</span>
</div>
<div className={styles.upload_right} onClick={() => removeFiles(index)}>
<DeleteOutlined />
</div>
</div>
))}
</div>
<Upload
action="/api/file/file/upload"
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>
</Upload>
</Form.Item>
</Form>
)
}
export default Attached;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, Tag, Badge } from 'antd';
import styles from './index.less';
import React, { useCallback, useState } from 'react';
import { Row, Col, Form, Input, Button } from 'antd';
import { LinkOutlined } from '@ant-design/icons';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { ISchema } from '@formily/antd';
import ModalTable from '@/components/ModalTable'
import { PublicApi } from '@/services/api'
import moment from 'moment';
import { EXTERNALSTATE_COLOR, INTERNALSTATE_COLOR } from '@/pages/transaction/components/stateColor';
import Card from '@/pages/transaction/components/card';
import TableModal from '@/pages/transaction/components/TableModal';
import { PublicApi } from '@/services/api';
const layout: any = {
colon: false,
labelCol: { style: { width: '100px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
};
const { Search } = Input;
interface queryProps {
currentRef?: any,
getMemberList?: Function,
editData: any
type?: number
interface BasicInfoLayoutProps {
/** 获取询价会员 */
getMemberInfo: (e) => void
}
const BasicInfo: React.FC<queryProps> = (props) => {
const format = (text, fmt?: string) => {
return <>{moment(text).format(fmt || "YYYY-MM-DD HH:mm:ss")}</>
}
const [basicform] = Form.useForm();
const { getMemberList, currentRef, editData, type } = props;
// 会员添加弹窗控制
const [visibleChannelMember, setVisibleChannelMember] = useState(false);
const [memberName, setmemberName] = useState<any>();
const [memberId, setmemberId] = useState<any>();
const [roleId, setroleId] = useState<any>();
const [memberRowSelection, memberRowCtl] = useRowSelectionTable({ customKey: 'id', type: 'radio' });
const handleOkAddMember = () => {
if (memberRowCtl.selectRow.length > 0) {
setVisibleChannelMember(false)
const memberInfo = {
name: memberRowCtl.selectRow[0].name,
memberId: memberRowCtl.selectRow[0].memberId,
memberRoleId: memberRowCtl.selectRow[0].roleId,
memberRoleName: memberRowCtl.selectRow[0].roleName
}
sessionStorage.setItem('memberInfo', JSON.stringify({
memberId: memberRowCtl.selectRow[0].memberId,
memberRoleId: memberRowCtl.selectRow[0].roleId,
}))
const BasicInfoLayout: React.FC<BasicInfoLayoutProps> = (props: any) => {
const { getMemberInfo } = props;
const [visible, setVisible] = useState<boolean>(false);
const [member, setMember] = useState<any>({})
setmemberId(memberRowCtl.selectRow[0].memberId)
setroleId(memberRowCtl.selectRow[0].roleId)
setmemberName(memberRowCtl.selectRow[0].name);
getMemberList(memberInfo); // 回传给父级
}
}
const handleCancelAddMember = () => {
setVisibleChannelMember(false)
}
const columnsSetMember: any[] = [
const columns: any = [
{
title: 'ID',
dataIndex: 'id',
......@@ -85,126 +42,75 @@ const BasicInfo: React.FC<queryProps> = (props) => {
key: 'levelTag',
}
]
const formSearch: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
"x-component": 'Search',
"x-component-props": {
placeholder: '请输入会员名称'
}
}
}
}
// 请求
const fetchMemberList = async (params) => {
console.log(params)
return new Promise((resolve, reject) => {
PublicApi.getMemberManagePlatformProviderPage({ ...params }).then(res => {
resolve(res.data)
})
});
}
// 选择会员弹框结束
useEffect(() => {
if (memberName) {
basicform.setFieldsValue({ 'memberId': memberId ? memberId : undefined })
}
}, [memberName])
/************* 页面的一些操作start *************/
// 拿到表单数据
const hadnleValidateFields = () => {
return new Promise((resolve) => {
basicform.validateFields().then(values => {
resolve({
state: true,
data: {
details: values.details,
memberId: values.memberId,
const handleFetchData = useCallback((params: any) => {
return new Promise(resolve => {
PublicApi.getMemberManagePlatformProviderPage({ ...params }).then(res => {
if (res.code !== 1000) {
return
}
})
}).catch(errorInfo => {
resolve({ state: false })
resolve(res.data)
})
})
}
useEffect(() => {
if (currentRef) {
const userAction = {
validateFields: () => hadnleValidateFields()
}
if (currentRef && typeof currentRef === 'function') {
currentRef(userAction);
}
if (currentRef && typeof currentRef !== 'function') {
currentRef.current = userAction;
}
}
}, [])
useEffect(() => {
if (Object.keys(editData).length > 0) {
basicform.setFieldsValue({
details: editData.details,
})
setmemberName(editData.memberName)
setmemberId(editData.memberId)
setroleId(editData.roleId)
const toggle = (flag: boolean) => {
setVisible(flag)
}
const handleLogisticOnOk = (selectRowKeys: string[] | number[], selectRowRecord: any) => {
const target = selectRowRecord[0];
getMemberInfo(target)
setMember(target)
toggle(false)
}
}, [editData])
/************* 页面的一些操作end *************/
return (
<>
<Form
{...layout}
form={basicform}
className={styles.revise_style}
<Card
id="basicInfoLayout"
title="基本信息"
>
<Form.Item label='询价单摘要' name='details' rules={[{ required: true, message: '请输入询价单摘要' }]}>
<Row gutter={[48, 24]}>
<Col span={12}>
<Form.Item label="询价单摘要" name="details" rules={[{ required: true, message: '请输入询价单摘要' }]}>
<Input />
</Form.Item>
<Form.Item label='被询价会员' name='memberId' rules={[{ required: true, message: '请选择被询价会员' }]}>
<Search disabled={type === 3 || type === 2} value={memberName ? memberName : undefined} readOnly enterButton={<><LinkOutlined /> 选择</>} onSearch={() => setVisibleChannelMember(true)} />
{memberName && <Button type='link' onClick={() => window.open(`/shop?shopId=${btoa(JSON.stringify({ memberId, roleId }))}`)}>查看会员详情</Button>}
</Form.Item>
<Form.Item label='询价单号' name='orderNumber'>
<span>{(Object.keys(editData).length > 0 && editData.inquiryListNo) ? editData.inquiryListNo : '-'}</span>
</Form.Item>
<Form.Item label='单据时间' name='time'>
<span>{(Object.keys(editData).length > 0 && editData.voucherTime) ? format(editData.voucherTime) : '-'}</span>
</Col>
<Col span={12}>
<Form.Item label="被询价会员" name='memberName' rules={[{ required: true, message: '请选择被询价会员' }]}>
<Input.Search onSearch={() => toggle(true)} readOnly enterButton={<Button style={{ height: '31.19px' }} icon={<LinkOutlined />}>选择</Button>} />
</Form.Item>
<Form.Item label='外部状态' name='external'>
<span>{(Object.keys(editData).length > 0 && editData.externalState) ? <Tag color={EXTERNALSTATE_COLOR[editData.externalState]}>{editData.externalStateName}</Tag> : '-'}</span>
</Form.Item>
<Form.Item label='内部状态' name='internal'>
<span>{(Object.keys(editData).length > 0 && editData.interiorState) ? <Badge status={INTERNALSTATE_COLOR[editData.interiorState]} text={editData.interiorStateName} /> : '-'}</span>
</Form.Item>
</Form>
{/* 选择会员弹框 */}
<ModalTable
modalTitle='选择会员'
confirm={handleOkAddMember}
cancel={handleCancelAddMember}
visible={visibleChannelMember}
forceRender={visibleChannelMember}
resetModal={{ destroyOnClose: true, forceRender: true }}
columns={columnsSetMember}
rowSelection={memberRowSelection}
fetchTableData={params => fetchMemberList(params)}
formilyProps={
{
ctx: { schema: formSearch }
}
}
</Col>
</Row>
<TableModal
modalType="Drawer"
visible={visible}
title="选择会员"
mode="radio"
tableProps={{
rowKey: 'id',
}}
fetchData={handleFetchData}
onClose={() => toggle(false)}
onOk={handleLogisticOnOk}
columns={columns}
schema={{
type: 'object',
properties: {
name: {
type: 'string',
"x-component": 'Search',
"x-component-props": {
placeholder: '请输入会员名称',
advanced: false
}
}
}
}}
value={[member]}
/>
</>
</Card>
)
}
export default BasicInfo
export default BasicInfoLayout;
import React, { useState, useEffect } from 'react';
import styles from './index.less';
import { Button, message, InputNumber, Table, Form } from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
import { PlusOutlined } from '@ant-design/icons';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd';
import ModalTable, { ModalTableProps } from '@/components/ModalTable';
import { PublicApi } from '@/services/api';
interface queryProps extends ModalTableProps {
member?: any,
schemaAction?: ISchemaFormActions | ISchemaFormAsyncActions,
getGoodsList: Function,
editData: any,
type?: number
}
const EnquiryGoods: React.FC<queryProps> = (props) => {
const { member, schemaAction, getGoodsList, editData, type, ...restProps } = props
// 会员添加弹窗控制
const [visibleChannelMember, setVisibleChannelMember] = useState(false);
const [goodsList, setgoodsList] = useState<any>([]);
const [memberRowSelection, memberRowCtl] = useRowSelectionTable({ customKey: 'productId' });
const [form] = Form.useForm()
const handleOkAddMember = () => {
setVisibleChannelMember(false);
setgoodsList(memberRowCtl.selectRow);
getGoodsList(memberRowCtl.selectRow);
}
const handleCancelAddMember = () => {
setVisibleChannelMember(false)
}
const columnsSetMember: any[] = [
{
title: 'ID',
dataIndex: 'productId',
key: 'productId',
},
{
title: '商品名称',
dataIndex: 'productName',
key: 'productName',
},
{
title: '品类',
dataIndex: 'category',
key: 'category',
},
{
title: '品牌',
dataIndex: 'brand',
key: 'brand',
}
]
/**输入框输入 */
const inputOnchange = (id, e) => {
const { value } = e.target
goodsList.forEach(v => {
if (v.productId === id) {
v.purchaseCount = value
}
})
getGoodsList(goodsList) // 返回给父级
setgoodsList(goodsList)
}
const columns: ColumnType<any>[] = [{
title: '序号',
dataIndex: 'productId',
}, {
title: '商品名称',
dataIndex: 'productName',
}, {
title: '品类',
dataIndex: 'category',
}, {
title: '品牌',
dataIndex: 'brand',
}, {
title: '单位',
dataIndex: 'unit',
}, {
title: '采购数量',
dataIndex: 'purchaseCount',
render: (text: any, record: any) => (
<Form.Item name={record.productId} noStyle initialValue={record.purchaseCount}>
<InputNumber
onBlur={(e) => inputOnchange(record.productId, e)}
min={1}
maxLength={25}
/>
</Form.Item>
)
}, {
title: '操作',
dataIndex: 'operation',
render: (text: any, record: any) => <Button type='link' onClick={() => handleDelete(record)}>删除</Button>
}]
const fetchGoodsList = (params) => {
return new Promise((resolve, reject) => {
PublicApi.getProductCommodityCommonGetCommodityListByBuyer({ ...params, priceTypeList: 2, memberId: member.memberId, shopType: 1 }).then(res => {
if (res.code === 1000) {
const data: any[] = [];
res.data.data.forEach((v, i) => {
data.push({
commodityId: v.commodityId,
productId: v.id,
productName: v.name,
category: v.customerCategoryName,
brand: v.brandName,
unit: v.unitName,
purchaseCount: 1,
logistics: v.logistics,
memberId: v.memberId,
memberRoleId: v.memberRoleId,
imgUrl: v.mainPic
})
})
resolve({
totalCount: res.data.totalCount,
data,
})
}
})
})
}
// 选择会员弹框结束
useEffect(() => {
// 重选会员清掉已选择的商品
if (member.memberId !== editData.memberId) {
setgoodsList([]);
memberRowCtl.setSelectRow([])
memberRowCtl.setSelectedRowKeys(goodsList.map(v => v.productId))
}
}, [member])
// 添加商品
const addGoods = () => {
if (member.name && member.memberId) {
setVisibleChannelMember(true);
} else {
message.error('请选择被询价会员')
}
}
useEffect(() => {
form.resetFields();
}, [])
// 删除
const handleDelete = (record) => {
const table_data = [...goodsList];
const idx = table_data.findIndex(v => v.productId === record.productId);
table_data.splice(idx, 1);
memberRowCtl.setSelectRow(table_data)
memberRowCtl.setSelectedRowKeys(table_data.map(v => v.productId))
setgoodsList(table_data)
getGoodsList(table_data)
}
// 编辑时回显的数据
useEffect(() => {
if (Object.keys(editData).length > 0) {
memberRowCtl.setSelectRow(editData.inquiryListProductRequests);
memberRowCtl.setSelectedRowKeys(editData.inquiryListProductRequests.map(v => v.productId))
setgoodsList(editData.inquiryListProductRequests);
}
}, [editData])
return (
<div className={styles.revise_style}>
<Button disabled={type === 3} block type='dashed' onClick={addGoods}><PlusOutlined />添加商品</Button>
<Form form={form}>
<Table rowKey={record => record.productId} style={{ marginTop: '16px' }} columns={columns} dataSource={goodsList} pagination={false} />
</Form>
{/* 选择商品弹框 */}
<ModalTable
modalTitle='选择商品'
confirm={handleOkAddMember}
cancel={handleCancelAddMember}
visible={visibleChannelMember}
forceRender={visibleChannelMember}
resetModal={{ destroyOnClose: true, forceRender: true }}
columns={columnsSetMember}
rowSelection={memberRowSelection}
fetchTableData={params => fetchGoodsList(params)}
modalType='productByMember'
tableProps={{
rowKey: 'productId'
}}
{...restProps}
/>
</div>
)
}
export default EnquiryGoods
import React, { useState } from 'react';
import styles from './index.less';
import { Radio, Tag } from 'antd';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import moment from 'moment';
import { EXTERNALSTATE_COLOR, INTERNALSTATE_COLOR } from '@/pages/transaction/components/stateColor';
export interface parmas {
editData?: any
}
const FlowRecord: React.FC<parmas> = (props) => {
const { editData } = props;
const [radio, setRadio] = useState<string>('outer'); //切换单据
const format = (text, fmt?: string) => {
return <>{moment(text).format(fmt || "YYYY-MM-DD HH:mm:ss")}</>
}
const outerColumns: EditableColumns[] = [{
title: '序号',
dataIndex: 'id',
}, {
title: '操作角色',
dataIndex: 'roleName',
}, {
title: '状态',
dataIndex: 'state',
render: (text: any, record: any) => <Tag color={EXTERNALSTATE_COLOR[text]}>{record.stateName}</Tag>
}, {
title: '操作',
dataIndex: 'operation',
}, {
title: '操作时间',
dataIndex: 'operationTime',
render: (text: any, record: any) => format(text)
}, {
title: '审核意见',
dataIndex: 'auditOpinion',
}]
const insideColumns: EditableColumns[] = [{
title: '序号',
dataIndex: 'id',
}, {
title: '操作人',
dataIndex: 'roleName',
}, {
title: '部门',
dataIndex: 'department',
}, {
title: '职位',
dataIndex: 'position',
}, {
title: '状态',
dataIndex: 'state',
render: (text: any, record: any) => <Tag color={INTERNALSTATE_COLOR[text]}>{record.stateName}</Tag>
}, {
title: '操作',
dataIndex: 'operation',
}, {
title: '操作时间',
dataIndex: 'operationTime',
render: (text: any, record: any) => format(text)
}, {
title: '审核意见',
dataIndex: 'auditOpinion',
}]
const onChange = (e: any) => {
setRadio(e.target.value)
}
return (
<div className={styles.revise_style}>
<Radio.Group defaultValue="outer" buttonStyle="solid" onChange={onChange}>
<Radio.Button value="outer">外部单据</Radio.Button>
<Radio.Button value="inside">内部单据</Radio.Button>
</Radio.Group>
{radio === 'outer' ?
<PolymericTable
dataSource={editData.externalInquiryListLogResponses}
columns={outerColumns}
loading={false}
pagination={null}
/>
:
<PolymericTable
dataSource={editData.interiorInquiryListLogResponses}
columns={insideColumns}
loading={false}
pagination={null}
/>
}
</div>
)
}
export default FlowRecord
.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, { useCallback, useEffect, useState } from 'react';
import { Button, Form, Table, InputNumber, Image } from 'antd';
import Card from '@/pages/transaction/components/card';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table/interface';
import TableModal from '@/pages/transaction/components/TableModal';
import { PublicApi } from '@/services/api';
import { isEmpty } from 'lodash';
interface InquiryProductLayoutProps {
/** 获得询价商品 */
getInquiryProduct: (e) => void,
/** 回显 */
setInquiryProduct?: any[],
/** 会员信息 */
member?: number,
}
const InquiryProductLayout: React.FC<InquiryProductLayoutProps> = (props: any) => {
const { getInquiryProduct, setInquiryProduct, member } = props;
const [visible, setVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>([]);
const [memberId, setMemberId] = useState<number>();
/** 改变采购数量 */
const setInputNumber = (val, index) => {
const data = [...dataSource];
data[index].purchaseCount = val;
setDataSource(data);
getInquiryProduct(data)
}
/** 删除 */
const handleDeleted = (index) => {
const data = [...dataSource];
data.splice(index, 1);
setDataSource(data);
getInquiryProduct(data)
}
const columns: ColumnType<any>[] = [
{
title: "商品ID",
key: "productId",
dataIndex: "productId",
},
{
title: "商品图片",
key: "imgUrl",
dataIndex: "imgUrl",
render: (text) => <Image width={32} height={32} src={text} />
},
{
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",
render: (text, _data, index) => (
<InputNumber min={1} defaultValue={text} onChange={(val) => setInputNumber(val, index)} />
)
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
render: (_text, _data, index) => (
<Button type="link" onClick={() => handleDeleted(index)}>删除</Button>
)
},
]
const productColumns: any[] = [
{
title: 'ID',
dataIndex: 'productId',
key: 'productId',
},
{
title: '商品名称',
dataIndex: 'productName',
key: 'productName',
},
{
title: '品类',
dataIndex: 'category',
key: 'category',
},
{
title: '品牌',
dataIndex: 'brand',
key: 'brand',
}
]
const handleFetchData = useCallback((params: any) => {
return new Promise(resolve => {
PublicApi.getProductCommodityCommonGetCommodityListByBuyer({ ...params, priceTypeList: 2, memberId, shopType: 1 }).then(res => {
if (res.code !== 1000) {
return
}
const data: any[] = [];
res.data.data.forEach((v, i) => {
data.push({
commodityId: v.commodityId,
productId: v.id,
productName: v.name,
category: v.customerCategoryName,
brand: v.brandName,
unit: v.unitName,
purchaseCount: 1,
logistics: v.logistics,
memberId: v.memberId,
memberRoleId: v.memberRoleId,
imgUrl: v.mainPic
})
})
resolve({
totalCount: res.data.totalCount,
data,
})
})
})
}, [memberId])
useEffect(() => {
if (!isEmpty(setInquiryProduct)) {
setDataSource([...setInquiryProduct])
}
}, [setInquiryProduct])
const toggle = (flag: boolean) => {
setVisible(flag)
}
const handleLogisticOnOk = (selectRowKeys: string[] | number[], selectRowRecord: any) => {
setDataSource(selectRowRecord)
getInquiryProduct(selectRowRecord)
toggle(false)
}
useEffect(() => {
if (!isEmpty(member)) {
console.log(member)
setMemberId(member.memberId)
}
}, [member])
return (
<Card
id="inquiryProductLayout"
title="询价商品"
>
<Button block type="dashed" style={{ marginBottom: "24px" }} onClick={() => toggle(true)}><PlusOutlined />添加商品</Button>
<Form.Item
name="inquiryListProductRequests"
rules={[{ required: true, message: "请添加商品" }]}
>
<Table
rowKey="productId"
columns={columns}
dataSource={dataSource}
pagination={false}
/>
</Form.Item>
<TableModal
modalType="Drawer"
visible={visible}
title="选择会员"
mode="checkbox"
tableProps={{
rowKey: 'productId',
}}
fetchData={handleFetchData}
onClose={() => toggle(false)}
onOk={handleLogisticOnOk}
columns={productColumns}
schema={{
type: 'object',
properties: {
name: {
type: 'string',
"x-component": 'Search',
"x-component-props": {
placeholder: '请输入会员名称',
advanced: false
}
}
}
}}
value={dataSource}
/>
</Card>
)
}
export default InquiryProductLayout;
import React, { useEffect, useState } from 'react';
import { Row, Col, Form, Input, DatePicker, Select } from 'antd';
import Card from '@/pages/transaction/components/card';
import moment from 'moment';
import { PublicApi } from '@/services/api';
import { isEmpty } from 'lodash';
const disabledDate = (current) => {
return current && current < moment().startOf('day');
}
interface TradeTermsLayoutProps {
/** 获取地址详情 */
getFullAddress?: (e) => void,
}
const TradeTermsLayout: React.FC<TradeTermsLayoutProps> = (props: any) => {
const { getFullAddress } = props;
const [fullAddress, setFullAddress] = useState<any[]>([]);
useEffect(() => {
PublicApi.getLogisticsSelectListReceiverAddress().then(res => {
if (res.code !== 1000) {
return
}
setFullAddress(res.data)
})
}, [])
const handleFullAddress = (_v, option) => {
getFullAddress(option)
}
return (
<Card
id="tradeTermsLayout"
title="交易条件"
>
<Row gutter={[48, 24]}>
<Col span={12}>
<Form.Item label='交付日期' name='deliveryTime' rules={[{ required: true, message: '请选择交付日期' }]}>
<DatePicker
style={{ width: '100%' }}
disabledDate={disabledDate}
format="YYYY-MM-DD HH:mm:ss"
/>
</Form.Item>
<Form.Item label='交付地址' name='fullAddressId' rules={[{ required: true, message: '请选择交付地址' }]}>
<Select onChange={handleFullAddress}>
{
!isEmpty(fullAddress) && (
fullAddress.map(item => (
<Select.Option
key={item.id}
value={item.id}
>
{item.fullAddress}
</Select.Option>
))
)
}
</Select>
</Form.Item>
<Form.Item label='报价截止时间' name='quotationAsTime' rules={[{ required: true, message: '请选择报价截止时间' }]}>
<DatePicker
style={{ width: '100%' }}
disabledDate={disabledDate}
format="YYYY-MM-DD HH:mm:ss"
/>
</Form.Item>
<Form.Item label='报价要求' name='offer'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='付款方式' name='paymentType'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label='税费要求' name='taxes'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='物流要求' name='logistics'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='包装要求' name='packRequire'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='其他要求' name='otherRequire'>
<Input.TextArea autoSize placeholder='最长100个字符,50个汉字' />
</Form.Item>
</Col>
</Row>
</Card>
)
}
export default TradeTermsLayout;
import React, { useState, useEffect } from 'react';
import styles from './index.less';
import moment from 'moment';
import { Form, Input, Select, Row, Col, DatePicker, message } from 'antd';
import { PublicApi } from '@/services/api';
interface queryProps {
currentRef?: any,
editData: any,
getAddress?: Function
}
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 24 },
labelAlign: "left"
};
const TradingConditions: React.FC<queryProps> = (props) => {
const { currentRef, editData, getAddress } = props;
const [TradingConditionsForm] = Form.useForm();
const [address, setAddress] = useState([]);
const hadnleValidateFields = () => {
return new Promise((resolve) => {
TradingConditionsForm.validateFields().then(values => {
resolve({
state: true,
data: {
deliveryTime: moment(values.deliveryTime).format('x'),
quotationAsTime: moment(values.quotationAsTime).format('x'),
offer: values.offer,
paymentType: values.paymentType,
taxes: values.taxes,
logistics: values.logistics,
packRequire: values.packRequire,
otherRequire: values.otherRequire,
}
})
}).catch(errorInfo => {
resolve({ state: false })
})
})
}
useEffect(() => {
if (currentRef) {
const userAction = {
validateFields: () => hadnleValidateFields()
}
if (currentRef && typeof currentRef === 'function') {
currentRef(userAction);
}
if (currentRef && typeof currentRef !== 'function') {
currentRef.current = userAction;
}
}
// 获取交付地址
PublicApi.getLogisticsSelectListReceiverAddress().then(res => {
setAddress(res.data)
})
}, [])
useEffect(() => {
// 编辑时回显的数据
if (Object.keys(editData).length > 0) {
TradingConditionsForm.setFieldsValue({
paymentType: editData.paymentType,
taxes: editData.taxes,
logistics: editData.logistics,
packRequire: editData.packRequire,
otherRequire: editData.otherRequire,
offer: editData.offer,
quotationAsTime: editData.quotationAsTime ? moment(editData.quotationAsTime) : undefined,
deliveryTime: editData.deliveryTime ? moment(editData.deliveryTime) : undefined,
fullAddressId: editData.fullAddressId,
})
}
}, [editData])
const addressOnChange = (value: any, option: any) => {
getAddress(option)
}
const disabledDate = (current) => {
return current && current < moment().endOf('day');
}
return (
<Form
{...layout}
form={TradingConditionsForm}
className={styles.revise_style}
>
<Row gutter={70}>
<Col span={12}>
<Form.Item label='交付日期' name='deliveryTime' rules={[{ required: true, message: '请选择交付日期' }]}>
<DatePicker
disabledDate={disabledDate}
format="YYYY-MM-DD HH:mm:ss"
/>
</Form.Item>
<Form.Item label='交付地址' name='fullAddressId' rules={[{ required: true, message: '请选择交付地址' }]}>
<Select onChange={addressOnChange}>
{address.map(v => (
<Select.Option key={v.id} value={v.id}>{v.fullAddress}</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label='报价截止时间' name='quotationAsTime' rules={[{ required: true, message: '请选择报价截止时间' }]}>
<DatePicker
format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
/>
</Form.Item>
<Form.Item label='报价要求' name='offer'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='付款方式' name='paymentType'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='税费要求' name='taxes'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='物流要求' name='logistics'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label='包装要求' name='packRequire'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item label='其他要求' name='otherRequire'>
<Input.TextArea placeholder='最长100个字符,50个汉字' />
</Form.Item>
</Col>
</Row>
</Form>
)
}
export default TradingConditions
import React from 'react';
import AddForm from './addForm';
import { history } from 'umi';
const EditEnquiryOrder:React.FC<{}> = () => {
import { PublicApi } from '@/services/api';
const EditEnquiryOrder:React.FC<{}> = (props: any) => {
const { id } = history.location.query;
console.log(id)
return(
<AddForm
id={id}
type={2}
isEdit
title={props.route.name}
fetchRequest={PublicApi.postTransactionInquiryListUpdate}
/>
)
}
......
import React from 'react';
import AddForm from './addForm';
import { history } from 'umi';
const RfqEnquiryOrder:React.FC<{}> = () => {
import { PublicApi } from '@/services/api';
const RfqEnquiryOrder = (props: any) => {
const { id, spam_id } = history.location.query;
return(
<AddForm
id={id}
type={3}
spam_id={spam_id}
isEdit
title={props.route.name}
fetchRequest={PublicApi.postTransactionInquiryListAdd}
spam={spam_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