Commit 016ed1d4 authored by rainbowmorel@163.com's avatar rainbowmorel@163.com

转单页面

parent 9221349f
......@@ -211,6 +211,24 @@ const TranactionRoute = {
// 销售订单
...saleOrder,
//订单转单
{
"path": "/memberCenter/tranactionAbility/transferOrder/orderList",
"name": "订单转单",
"routes": [
{
"path": "/memberCenter/tranactionAbility/transferOrder/orderList",
"component": "@/pages/transaction/transferOrder",
"name": "订单列表",
},
{
"path": "/memberCenter/tranactionAbility/transferOrder/orderList/details",
"component": "@/pages/transaction/transferOrder/details",
"name": "订单列表",
},
]
},
// 交易规则
{
path: '/memberCenter/tranactionAbility/transactionRules',
......
import React, { useState } from "react";
import { Card, Table, Modal, Button, Form, Select, Input, Tag } from "antd";
import { TransferOrderCloums, TransferOrderGoodsCloums } from "../types/table-props";
import AutoCancelModel from "../components/AutoCancelModel";
const FormItem = Form.Item
function GoodsTable() {
const [showModel, setShowModel] = useState(0);
return (
<Card
id="OrderInfo"
title="订单商品"
className="mt-10"
extra={
<div className="flex flex-row order_total space-x-10">
<div className="order_total">
<div className="title text-gray-400">合计金额</div>
<div className="total">¥1200.00</div>
</div>
<div className="order_total">
<div className="title">合计金额</div>
<div className="total">¥1200.00</div>
</div>
<div className="order_total">
<div className="title">合计金额</div>
<div className="total">¥1200.00</div>
</div>
<div className="order_total">
<div className="title">合计金额</div>
<div className="total">¥1200.00</div>
</div>
</div>
}>
<Table
columns={TransferOrderCloums}
expandable={{
expandedRowRender: record => {
return (
<Table
columns={TransferOrderGoodsCloums}
/>
);
},
rowExpandable: record => record.name !== 'Not Expandable'
}}
/>
<Button onClick={() => {
console.log(showModel)
setShowModel(showModel + 2)
}}>转单功能封装</Button>
<AutoCancelModel isShow={showModel} title="转单">
<Form layout="vertical">
<FormItem label="上游供应链" required>
<Select>
<Select.Option value="1">上游供应会员名称S1</Select.Option>
</Select>
</FormItem>
<FormItem label="上商品" required>
<Select>
<Select.Option value="1">
1110/进口头层黄牛荔枝纹
</Select.Option>
</Select>
</FormItem>
<FormItem label="上游商品库存">
1,000
</FormItem>
<FormItem label="转单数量" required>
<Input />
</FormItem>
<FormItem label="转单单价" required>
<Input />
</FormItem>
<FormItem label="转单金额" required>
<Input />
</FormItem>
<FormItem label="转单金额">
<Tag color={"yellow"}>转单金额</Tag>
</FormItem>
</Form>
</AutoCancelModel>
</Card>
)
}
export default GoodsTable;
\ No newline at end of file
import { Card } from 'antd';
import React from 'react';
function PayInfo() {
return (
<Card
id='PayInfo'
title="支付信息"
className='mt-10'
>
<div className='payinfo grid grid-cols-4 gap-4'>
<div className='payinfo_item relative border-dashed leading-9 border-gray-300 p-8'>
<div className='text-gray-400'>
支付比例
</div>
<div className='proportion text-6xl font-medium mt-2 mb-2'>
30%
</div>
<div className='price font-medium text-lg'>
¥48,000.00
</div>
<div className='list_item flex'>
<div className='flex-4 flex-grow-0 text-gray-400'>支付环节:</div>
<div className='flex-auto value font-medium'>订单确认后支付</div>
</div>
<div className='list_item flex'>
<div className='flex-4 flex-grow-0 text-gray-400'>支付方式:</div>
<div className='flex-auto value font-medium'>线上支付</div>
</div>
<div className='list_item flex'>
<div className='flex-4 flex-grow-0 text-gray-400'>支付渠道:</div>
<div className='flex-auto value font-medium'>支付宝</div>
</div>
<div className='absolute top-0 right-0 bg-green-100 text-green-700 p-1'>
确认到账
</div>
</div>
</div>
</Card>
)
}
export default PayInfo;
\ No newline at end of file
import { Modal } from "antd";
import { useEffect, useState } from "react";
/**
*
* @param param0
* isShow %2 === 0 的时候显示,父元素必须又0开始
* @returns
*/
function AutoCancelModel(props: {
isShow: number,
children?: JSX.Element | string | JSX.Element[]
title?: string
width?: number
onOk?: Function
}) {
const {
isShow,
children,
title,
width
} = props;
const [visible, setVisible] = useState<boolean>();
useEffect(() => {
setVisible(isShow > 0 && isShow % 2 === 0)
}, [isShow])
return (
<Modal
title={title}
visible={visible}
onCancel={() => { setVisible(false) }}
width={width}
onOk={async () => {
let isClose = await props.onOk()
setVisible(isClose)
}}
>
{children}
</Modal>
)
}
export default AutoCancelModel;
\ No newline at end of file
import { Card } from 'antd';
import React from 'react';
interface BaseInfoPorps {
title?: string
className?: string
children: JSX.Element[]
cols?: number,
id?: string
}
/**
* 基础信息布局 Card
* @param param0
* @returns
*/
function BaseInfo({ title, className, children, cols = 2, id }: BaseInfoPorps) {
return (
<Card
id={id}
title={title}
className={className}
>
<div className={`base_info grid grid-cols-${cols} gap-4`}>
{children}
</div>
</Card>
)
}
function BaseInfoItem({ label, children }: {
label: string
children: JSX.Element | string
}) {
return (
<div className='base_info_item flex text-lg'>
<div className='label flex-grow-0 w-60 text-gray-400'>
{label}
</div>
<div className='value font-semibold'>
{typeof children === 'string' ? <span>{children}</span> : children}
</div>
</div>
)
}
BaseInfo.BaseInfoItem = BaseInfoItem;
export default BaseInfo;
\ No newline at end of file
import { ClockCircleOutlined } from '@ant-design/icons';
import { Button, Steps } from 'antd';
import react, { useState } from 'react';
import classnames from 'classnames';
const { Step } = Steps;
/**
* 流转换组件
* @param param0
* showClockIcon true 是否显示时间ICON
* btnsName ["内部流转","外部流转"]
* steps [{ 注意这里的 顺序需要和 btnsName 对应
* current: 当前的状态
* list: title description
* }]
* @returns
*/
function FlowSwitchSteps({ children, steps, btnsName, showClockIcon = false, id }: {
children?: JSX.Element,
btnsName?: string[],
showClockIcon?: boolean,
id?: string,
steps?: {
current: number,
list: {
title: string,
description: string
}[]
}[]
}): JSX.Element {
const [action, setAction] = useState<number>(0);
const ActionClass = 'border-green-600 text-green-600';
function renderSteps(steps) {
return (
<Steps progressDot current={steps.current} >
{steps.list.map(item => {
return <Step title={item.title} description={item.description} />
})}
</Steps >
)
}
return (
<div className='flow_switch_steps bg-white p-8 rounded'>
<div className='flex'>
<div className='flex-1'>
<h2>流转进度</h2>
</div>
<div className=' flex flex-auto flex-row-reverse items-center'>
<div className='switch_btns'>
{btnsName.map((name, index) => {
return (
<Button
size='small'
onClick={() => {
setAction(index)
}}
className={classnames(
{
[ActionClass]: action === index
},
'mr-3'
)}>
{name}
</Button>
)
})}
</div>
{showClockIcon && <div className='time mr-3'><ClockCircleOutlined /></div>}
</div>
</div>
<div className='flow_body mt-20'>
{children ? children : renderSteps(steps[action])}
</div>
</div>
);
}
export default FlowSwitchSteps;
\ No newline at end of file
import { ArrowLeftOutlined } from "@ant-design/icons";
import { Button } from "antd";
import classNames from "classnames";
import React, { useEffect, useState } from "react";
import { useHistory } from "umi";
interface PageHeaderProps {
title?: JSX.Element | string
layout?: 'vertical' | 'inline'
children?: JSX.Element | React.ReactNode | string
extraRight?: JSX.Element | React.ReactNode | string
}
function PageHeader({
title,
layout = 'vertical',
children,
extraRight
}: PageHeaderProps) {
const history = useHistory();
const [isFixed, setIsFixed] = useState<boolean>(false)
useEffect(() => {
window.addEventListener("scroll", onScroll)
return (() => {
window.removeEventListener('scroll', onScroll)
})
}, [])
const onScroll = () => {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let floors = document.querySelectorAll(".page_heder_content")
floors.forEach((floor: any, index: any) => {
if (scrollTop > 50) {
setIsFixed(true) //top-0
} else {
setIsFixed(false)// top-23
}
})
}
return (
<div
className={classNames({
'page-header p-8 bg-white fixed z-30': true,
'top-0': isFixed
})}
style={{
width: document.querySelector('.ant-layout-header').clientWidth
}}
>
<div className='flex page_header_default'>
<div className='flex flex-1 items-center'>
<ArrowLeftOutlined onClick={() => history.goBack()} className="mr-4" />
<div className='text-3xl font-bold'>{title}</div>
</div>
<div className='flex flex-1 flex-row-reverse'>
{extraRight}
</div>
</div>
<div className="page_heder_content">
{children}
</div>
</div>
);
}
export default PageHeader;
\ No newline at end of file
.ant-anchor{
position: relative;
display: flex;
.ant-anchor-ink{
display: none;
}
.ant-anchor-link{
padding: 16px;
transition: all .375s ease-in-out;
}
.ant-anchor-link.ant-anchor-link-active{
position: relative;
&::before{
position: absolute;
bottom: 0;
background-color: rgb(0, 169, 143);
height: 2px;
width: 100%;
left: 0;
content: ' ';
}
}
}
\ No newline at end of file
import EyePreview from '@/components/EyePreview';
import { Anchor, Button, Card, Form, Radio, Table, } from 'antd';
import React, { useEffect, useState } from 'react';
import { Link, useIntl, } from 'umi';
import GoodsTable from './business/Goods';
import PayInfo from './business/PayInfo';
import AutoCancelModel from './components/AutoCancelModel';
import BaseInfo from './components/BaseInfo';
import FlowSwitchSteps from './components/FlowSwitchSteps';
import PageHeader from './components/PageHeader';
const { BaseInfoItem } = BaseInfo;
import './details.less';
import { SupplierTableCloums } from './types/table-props';
function TransferOrderDetail() {
const intl = useIntl()
const [showSubmitModal, setShowSubmitModal] = useState<number>(0);
return (
<div style={{ margin: -24 }}>
<PageHeader
title="进口头层黄牛荔纹|DPTY12"
extraRight={
<Button
type='primary'
onClick={() => {
setShowSubmitModal(showSubmitModal + 2)
}}
>
保存
</Button>
}
>
<Anchor
targetOffset={120}
affix={false}>
<Anchor.Link href='#Transfer' title="流转信息" />
<Anchor.Link href='#BasicInfo' title="基本信息" />
<Anchor.Link href='#OrderInfo' title="订单信息" />
<Anchor.Link href='#PayInfo' title="支付信息" />
<Anchor.Link href='#Delivery' title="送货信息" />
<Anchor.Link href='#Contract' title="电子合同" />
<Anchor.Link href='#Invoice' title="发票信息" />
<Anchor.Link href='#Other' title="其他信息" />
<Anchor.Link href='#Adjunct' title="附件" />
</Anchor>
</PageHeader>
<div className='p-10 pt-56 transfer_content'>
<FlowSwitchSteps
id='Transfer'
showClockIcon={true}
btnsName={["内部流转", "内部流转"]}
steps={[
{
current: 0,
list: [
{
title: '提交订单',
description: '采购商'
},
{
title: '提交订单',
description: '采购商'
},
{
title: '提交订单',
description: '采购商'
}
]
},
{
current: 3,
list: [
{
title: '提交订单1',
description: '采购商'
},
{
title: '提交订单2',
description: '采购商'
},
{
title: '提交订单3',
description: '采购商'
}
]
}
]} />
<BaseInfo id="BasicInfo" className="mt-10" title='基本信息'>
<BaseInfoItem label="订单号码:">DPTYI2</BaseInfoItem>
<BaseInfoItem label="供应会员:">
<Link to={"/"}>广州马皮具交易中心</Link>
</BaseInfoItem>
</BaseInfo>
<GoodsTable />
<PayInfo />
<BaseInfo
id='Delivery'
cols={1}
className="mt-10"
title='送货信息'>
<BaseInfoItem label="送货日期:">
2020-08-25
</BaseInfoItem>
<BaseInfoItem label="送货地址:">
<div>
张三 / 185 2929 6758 <br />
广州马皮具交易中心
</div>
</BaseInfoItem>
</BaseInfo>
<Card id='Contract' className='mt-10' title="电子合同">
<EyePreview>
广州马皮具交易中心购销合同.pdf
</EyePreview>
</Card>
<BaseInfo
id='Invoice'
cols={2}
className="mt-10"
title='发票信息'>
<BaseInfoItem label="需要发票:">
</BaseInfoItem>
<BaseInfoItem label="发票抬头:">
<div>
温州市皮革工业有限公司
</div>
</BaseInfoItem>
</BaseInfo>
<BaseInfo
id='Other'
cols={2}
className="mt-10"
title='其他信息'>
<BaseInfoItem label="保证要求:">
纸箱
</BaseInfoItem>
<BaseInfoItem label="备注:">
<div>
要求准时到货
</div>
</BaseInfoItem>
</BaseInfo>
<Card
id="Adjunct"
className='mt-10' title="附件">
<EyePreview>
广州马皮具交易中心购销合同.xls
</EyePreview>
</Card>
</div>
<AutoCancelModel
title='订单转单'
isShow={showSubmitModal}
width={1200}
onOk={async () => {
return true
}}
>
<div className='finish_sumbit_from'>
<div className='role_type'>
<div className='label text-gray-400'>
转单后的角色会员
<span className='text-red-600'>*</span>
</div>
<div className='control mt-4'>
<Radio.Group>
<Radio.Button value={1}>采购商(默认)</Radio.Button>
<Radio.Button value={2}>采购商(个人)</Radio.Button>
</Radio.Group>
</div>
</div>
<div className='supplier_table'>
<Table
className='mt-4'
columns={SupplierTableCloums}
/>
</div>
</div>
</AutoCancelModel>
</div>
);
}
export default TransferOrderDetail;
\ No newline at end of file
import React, { useRef, useState } from 'react';
import StandardTable from '@/components/StandardTable';
import { useHistory, useIntl } from 'umi';
import EyePreview from '@/components/EyePreview';
import { StandardTableProps } from './types/table-props';
import { createFormActions, Submit } from '@formily/antd';
import NiceForm from '@/components/NiceForm';
import { TableListSchema } from './schemas/table';
import DateRangePickerUnix from '@/components/NiceForm/components/DateRangePickerUnix';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { getOrderVendorPage } from '@/services/OrderNewV2Api';
import { Button, Card, Space } from 'antd';
function TransferOrder() {
const history = useHistory();
const intl = useIntl();
const [columns] = useState<StandardTableProps[]>(() => [
{
title: intl.formatMessage({ id: 'saleOrder.dingdanhao', defaultMessage: '订单号' }),
dataIndex: 'orderNo',
key: 'orderNo',
render: (text, record) => {
return (
<EyePreview url={`${history.location.pathname}/details?id=${record.orderId}`}>
{text}
</EyePreview>
)
},
},
{
title: intl.formatMessage({ id: 'transferOrder.purchasingMember', defaultMessage: "采购会员" }),
dataIndex: 'purchasingMember',
key: 'purchasingMember',
},
{
title: intl.formatMessage({ id: 'transferOrder.totalAmount', defaultMessage: "订单总金额" }),
dataIndex: 'totalAmount',
key: 'totalAmount',
},
{
title: intl.formatMessage({ id: 'transferOrder.time', defaultMessage: "下单时间" }),
dataIndex: 'time',
key: 'time',
},
{
title: intl.formatMessage({ id: 'transferOrder.abstract', defaultMessage: "订单摘要" }),
dataIndex: 'abstract',
key: 'abstract',
},
{
title: intl.formatMessage({ id: 'transferOrder.type', defaultMessage: "订单类型" }),
dataIndex: 'type',
key: 'type',
},
{
title: intl.formatMessage({ id: 'transferOrder.address', defaultMessage: "送货地址" }),
dataIndex: 'address',
key: 'address',
},
{
title: intl.formatMessage({ id: 'transferOrder.TurnSingleState', defaultMessage: "转单状态" }),
dataIndex: 'TurnSingleState',
key: 'TurnSingleState',
},
{
title: intl.formatMessage({ id: 'transferOrder.internalState', defaultMessage: "内部状态" }),
dataIndex: 'internalState',
key: 'internalState',
},
{
title: intl.formatMessage({ id: 'transferOrder.outternalState', defaultMessage: "外部状态" }),
dataIndex: 'outternalState',
key: 'outternalState',
},
{
title: intl.formatMessage({ id: 'transferOrder.option', defaultMessage: "操作" }),
dataIndex: 'option',
key: 'option',
render: (text, record) => {
return (
<>
</>
)
}
},
])
const ref = useRef<any>({});
const formActions = createFormActions();
const fetchParams = useRef<any>({})
const loadingTableData = (params) => {
fetchParams.current = { ...params }
return fetchTableData(params)
}
async function fetchTableData(params: any) {
const { data } = await getOrderVendorPage(params)
return data
}
const [selectedRowKeys, setSelectedRowKeys] = useState<Array<number>>([])
const selectRef = useRef([])
const rowSelection = {
selectedRowKeys: selectedRowKeys,
onChange: (selectedRowKeys) => {
setSelectedRowKeys(selectedRowKeys)
selectRef.current = selectedRowKeys
},
getCheckboxProps: (record) => ({
disabled: !record.showTransfer,
name: record.name,
}),
}
const controllerBtns = (
<Space>
<Button style={{ width: 140 }} type='default'>{intl.formatMessage({ id: 'saleOrder.daochu', defaultMessage: '导出' })}</Button>
</Space>
)
return (
<Card>
<StandardTable
fetchTableData={parmas => loadingTableData(parmas)}
columns={columns}
rowKey="orderId"
currentRef={ref}
rowSelection={rowSelection}
controlRender={
<NiceForm
actions={formActions}
schema={TableListSchema()}
onSubmit={values => ref.current.reload(values)}
expressionScope={{
controllerBtns,
}}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'orderNo',
FORM_FILTER_PATH,
)
}}
components={{
DateRangePickerUnix,
Submit
}}
/>
}
>
</StandardTable>
</Card>
)
}
export default TransferOrder;
import { FORM_FILTER_PATH } from "@/formSchema/const";
import { getIntl } from "umi"
const intl = getIntl();
export const TableListSchema: any = () => {
return {
type: 'object',
properties: {
mageLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
},
properties: {
ctl: {
type: 'object',
'x-component': 'Children',
'x-component-props': {
children: '{{controllerBtns}}',
},
},
orderNo: {
type: 'string',
"x-component": 'Search',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'purchaseOrder.readyAddOrder.orderNo' }),
align: 'flex-end',
},
}
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
},
colStyle: {
marginLeft: 20,
},
},
properties: {
"digest": {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'purchaseOrder.readyAddOrder.digest' }),
}
},
"memberName": {
type: 'string',
"x-component-props": {
placeholder: intl.formatMessage({ id: 'saleOrder.qingshurucaigouMemberName' })
}
},
"outerStatus": {
type: 'string',
"x-component-props": {
placeholder: `${intl.formatMessage({ id: 'common.text.pleaseSelect' })}${intl.formatMessage({ id: 'purchaseOrder.waibuzhuangtai' })}`
},
enum: [{
label: 'text',
value: 'id',
}]
},
"[startDate,endDate]": {
type: 'daterange',
// "x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: [intl.formatMessage({ id: 'purchaseRequisition.kaishishijian' }), intl.formatMessage({ id: 'purchaseRequisition.jieshushijian' })],
},
},
submit: {
'x-component': 'Submit',
'x-component-props': {
children: intl.formatMessage({ id: 'purchaseRequisition.chaxun' }),
},
},
},
}
}
},
}
}
}
\ No newline at end of file
import EyePreview from "@/components/EyePreview"
import { Select, Tag } from "antd"
export interface StandardTableProps {
title?: string
dataIndex?: string
key?: string
fixed?: 'left' | 'right'
render?: (text?: string, record?: any) => any
}
export const TransferOrderCloums: StandardTableProps[] = [
{
title: "商品ID",
render: (text, record) => {
return (
<EyePreview url={`/`}>
{text}
</EyePreview>
)
}
},
{
title: "商品图片",
render: (t, r) => {
return (
<img src={t} className="w-15 h-15 min-h-full max-w-full" />
)
}
},
{
title: "商品名称",
dataIndex: "goodName"
},
{
title: "品类",
dataIndex: "type"
},
{
title: "品牌",
dataIndex: "brand"
},
{
title: "单位",
dataIndex: "unit"
},
{
title: "采购数量",
dataIndex: "number"
},
{
title: "含税/税率",
dataIndex: "tax"
},
{
title: "会员折扣",
dataIndex: "discount",
render: (t, r) => {
return (
<Tag color={"red"}>80%</Tag>
)
}
},
{
title: "单价",
dataIndex: "price"
},
{
title: "金额",
dataIndex: "total"
},
{
title: "配送方式",
render: (t, r) => {
return (
t
);
}
},
{
title: "累计转单",
render: (t, r) => {
return (
t
);
}
},
{
title: "转单状态",
render: (t, r) => {
return (
t
);
}
},
{
title: "操作",
fixed: 'right',
render: (t, r) => {
return (
t
);
}
}
]
export const TransferOrderGoodsCloums: StandardTableProps[] = [
{
title: "序号",
dataIndex: 'id'
},
{
title: "上游供应会员名称",
render: (t, r) => {
return t;
}
},
{
title: "上游商品ID",
render: (t, r) => {
return t;
}
},
{
title: "商品图片",
render: (t, r) => {
return t;
}
},
{
title: "商品名称",
render: (t, r) => {
return t;
}
},
{
title: "品类",
render: (t, r) => {
return t;
}
},
{
title: "品牌",
render: (t, r) => {
return t;
}
},
{
title: "单位",
render: (t, r) => {
return t;
}
},
{
title: "转发数量",
render: (t, r) => {
return t;
}
},
{
title: "转发单价",
render: (t, r) => {
return t;
}
},
{
title: "转发金额",
render: (t, r) => {
return t;
}
},
{
title: "转发状态",
render: (t, r) => {
return t;
}
},
{
title: "转发订单号",
render: (t, r) => {
return t;
}
},
{
title: "转发订单号",
fixed: 'right',
render: (t, r) => {
return t;
}
}
]
export const SupplierTableCloums: StandardTableProps[] = [
{
title: "序号",
dataIndex: 'id'
},
{
title: "转单订单号",
dataIndex: 'id'
},
{
title: "上游供应会员名称S1",
dataIndex: 'id'
},
{
title: "发货模式",
dataIndex: 'id',
render: (t, r) => {
return (
<Select>
<Select.Option value="1">上游会员采购会员</Select.Option>
</Select>
)
}
},
{
title: "操作",
render: (t, r) => {
return (
<></>
)
}
},
];
\ No newline at end of file
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