Commit a52f5c26 authored by Bill's avatar Bill

修改首页以及加工

parent 07463e79
......@@ -25,6 +25,8 @@ import capitalAccount from './capitalAccountRoute'; // 会员资金账户
import messageRoute from './messgeRoute'; // 消息管理
import systemManageRoute from './systemManageRoute'; // 系统管理
import orderSystemRoutes from './orderSystemRoutes'; // 订单管理
import productionNoticeRoutes from './productionNoticeRoute'; // 生产通知单管理
const routeList = [
pageCustomized,
calssPropertyRoute,
......@@ -44,7 +46,8 @@ const routeList = [
capitalAccount,
messageRoute,
systemManageRoute,
orderSystemRoutes
orderSystemRoutes,
productionNoticeRoutes
]
const router = [
......
/**
* @author Bill
* @description 生产通知单
*/
const router = {
path: '/productionNoticeManage',
name: 'productionNotice',
icon: 'SmileOutlined',
routes: [
{
// 列表
path: '/productionNoticeManage/productionNotice',
name: 'query',
hidePageHeader: true,
component: '@/pages/productionNotice/query',
},
{
// 详情
path: '/productionNoticeManage/productionNotice/detail',
name: 'detail',
hidePageHeader: true,
component: '@/pages/productionNotice/detail',
hideInMenu: true
}
]
}
export default router
\ No newline at end of file
......@@ -46,9 +46,9 @@
"classnames": "^2.2.6",
"core-js": "^3.6.5",
"crypto-js": "^4.0.0",
"god": "0.1.29",
"god": "^0.1.29",
"lingxi-design": "^1.0.8",
"lingxi-design-ui": "^1.1.14",
"lingxi-design-ui": "^1.1.15",
"lingxi-editor-core": "^1.0.6",
"lingxi-web": "^1.0.6",
"lint-staged": "^10.0.7",
......@@ -59,6 +59,7 @@
"query-string": "^6.13.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"styled-components": "^5.2.1",
"umi": "^3.2.0",
"yorkie": "^2.0.0"
},
......
......@@ -221,5 +221,9 @@ export default {
'menu.system.unitAdd': '新建单位',
'menu.system.unitEdit': '编辑单位',
'menu.system.platformArg': '平他参数',
'menu.productionNotice': '生产通知单管理',
'menu.productionNotice.query': '生产通知单查询',
'menu.productionNotice.detail': '生产通知单详情',
}
// export default utils.transformDataPre(data, 'menu')
import React from 'react';
import React, { useEffect, useState} from 'react';
import { Row, Col } from 'antd';
import styles from './index.less';
import cx from 'classnames';
import { RightOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api'
// 收付款图标
import feeIcon1 from '@/asserts/home-icon-15.png'
......@@ -11,10 +12,38 @@ import feeIcon3 from '@/asserts/home-icon-17.png'
import feeIcon4 from '@/asserts/home-icon-18.png'
import feeIcon5 from '@/asserts/home-icon-19.png'
import feeIcon6 from '@/asserts/home-icon-20.png'
import {useInViewport} from '@umijs/hooks';
const Settlement: React.FC = () => {
const [settlements, setSettlements] = useState<any>({});
//@ts-ignore
// const [productInViewPort] = useInViewport(() => document.querySelector('#product'));
const [inViewPort, ref] = useInViewport<HTMLDivElement>();
const [settlementStatus, setSettlementStatus] = useState({
hasGetData: false,
loading: false,
})
/**
* /report/platform/home/getTradeAndAfterSaleTally
* 获取交易与售后计数报表
*/
useEffect(() => {
if(inViewPort && !settlementStatus.hasGetData) {
setSettlementStatus((state) => ({...state, loading: true }))
PublicApi.getReportPlatformHomeGetAccountAndSettleAccountTally()
.then(({data, code}) => {
setSettlementStatus((state) => ({...state, loading: false, hasGetData: true }))
if(code === 1000) {
// setOrderData(data);
setSettlements(data);
console.log(data);
}
})
}
}, [inViewPort])
return (
<Row gutter={[24, 12]} style={{marginTop: 9, marginBottom: 0}}>
<Row gutter={[24, 12]} style={{marginTop: 9, marginBottom: 0}} ref={ref}>
<Col span={5} style={{paddingBottom:0}}>
<div className={styles.notePaperBox}>
<div className={styles.notePaperContainer}>
......@@ -24,7 +53,7 @@ const Settlement: React.FC = () => {
</div>
<div className={styles.noteGap}></div>
<div className={styles.noteBody}>
<span className={styles.value}>15</span>
<span className={styles.value}>{settlements.toBePay?.count}</span>
<a>查看 <RightOutlined /></a>
</div>
</div>
......@@ -39,32 +68,32 @@ const Settlement: React.FC = () => {
</div>
<div className={styles.noteGap}></div>
<div className={styles.noteBody}>
<span className={styles.value}>15</span>
<span className={styles.value}>{settlements.complete?.count}</span>
<a>查看 <RightOutlined /></a>
</div>
</div>
</div>
</Col>
<Col span={7} style={{paddingBottom:0}}>
<Row gutter={[0, 24]}>
<Row >
<Col span={24} style={{padding:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon3} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTitle}>{settlements.tobeValifyCashout?.count}</p>
<p className={styles.lineDescTip}>待提现申请</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
<Col span={24} style={{paddingBottom:0}}>
<Col span={24} style={{paddingBottom:0, marginTop: '12px'}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon4} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTitle}>{settlements.tobePayCashout?.count}</p>
<p className={styles.lineDescTip}>待支付提现申请</p>
</div>
</div>
......@@ -74,25 +103,25 @@ const Settlement: React.FC = () => {
</Row>
</Col>
<Col span={7} style={{paddingBottom:0}}>
<Row gutter={[0, 24]}>
<Row>
<Col span={24} style={{padding:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon5} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTitle}>{settlements.scoreToBePay?.count}</p>
<p className={styles.lineDescTip}>待付款积分结算</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
<Col span={24} style={{paddingBottom:0}}>
<Col span={24} style={{paddingBottom:0, marginTop: '12px'}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon6} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTitle}>{settlements.scoreComplete?.count}</p>
<p className={styles.lineDescTip}>已完成积分结算</p>
</div>
</div>
......
import React from 'react';
import { Row, Col, Card, Space } from 'antd'
import { Row, Col, Card, Space, Skeleton } from 'antd'
import styles from './index.less';
import cx from 'classnames';
import { RightOutlined } from '@ant-design/icons'
......@@ -8,68 +8,102 @@ import totalIcona3 from '@/asserts/home-icon-10.png'
import totalCommdity from '@/asserts/home-icon-13.png'
import totalBrand1 from '@/asserts/home-icon-21.png'
import totalBrand2 from '@/asserts/home-icon-22.png'
import { Link } from 'umi';
const StatisticsColumn = () => {
const data = [
{
title: '商品统计',
value: '124,754',
icon: totalCommdity,
addIcon: totalIcona3,
},
{
title: '品牌统计',
value: '124,754',
icon: totalBrand1,
addIcon: totalBrand2,
}
]
const StatisticsColumn = (props) => {
const { loading, data } = props;
return (
<Row gutter={[24, 12]}>
{
data.map((item, key) => {
return (
<Col span={12} key={key}>
<Col span={12}>
<Row>
<Col span={24}>
<Card
headStyle={{borderBottom:'none'}}
title={item.title}
title={"商品统计"}
bordered={false}
>
{
loading
? <Skeleton active />
: <>
<div className={styles.commodityTotalTitle}>
<span>全部商品</span>
<p>124,754</p>
<p>{data?.productCount}</p>
</div>
<div className={styles.commodityTotalDesc}>
<div className={styles.container}>
<div className={styles.left}>
<img src={item.icon} alt=""/>
<img src={totalCommdity} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>待审核商品</p>
<p className={styles.lineDescTitle}>{data.addProduct?.count}</p>
<p className={styles.lineDescTip}>{data.addProduct?.name}</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
<div className={styles.container}>
<div className={styles.left}>
<img src={item.addIcon} alt=""/>
<img src={totalIcona3} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>待审核商品</p>
<p className={styles.lineDescTitle}>{data.toBeProductValify?.count}</p>
<p className={styles.lineDescTip}>{data.toBeProductValify?.name}</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</div>
</>
}
</Card>
</Col>
</Row>
</Col>
)
})
<Col span={12}>
<Row>
<Col span={24}>
<Card
headStyle={{borderBottom:'none'}}
title={"全部品牌"}
bordered={false}
>
{
loading
? <Skeleton active />
: <>
<div className={styles.commodityTotalTitle}>
<span>全部品牌</span>
<p>{data?.brandCount}</p>
</div>
<div className={styles.commodityTotalDesc}>
<div className={styles.container}>
<div className={styles.left}>
<img src={totalBrand1} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>{data.addBrand?.count}</p>
<p className={styles.lineDescTip}>{data.addBrand?.name}</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
<div className={styles.container}>
<div className={styles.left}>
<img src={totalBrand2} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>{data.toBeBrandValify?.count}</p>
<p className={styles.lineDescTip}>{data.toBeBrandValify?.name}</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</div>
</>
}
</Card>
</Col>
</Row>
</Col>
</Row>
)
}
......
import React, { useState, useEffect, useRef } from 'react'
import { Card, Space, Row, Col, List } from 'antd'
import { Card, Space, Row, Col, List, Skeleton, Badge } from 'antd'
import { RightCircleFilled, RightOutlined } from '@ant-design/icons'
import styles from './index.less'
import TodayAdd from './components/TodayAdd';
......@@ -14,17 +14,38 @@ import sideIcon from '../../asserts/home-icon-28.png'
import { ImemberData, IorderData, ItodayAdd } from './common/interface';
import {useInViewport} from '@umijs/hooks';
const PROCESS_STATUS = ["default", "warning", "warning", "processing"]
const Home: React.FC<{}> = () => {
const [memberData, setMemberData] = useState<ImemberData | {}>({});
const [orderData, setOrderData] = useState<IorderData | {}>({});
const [todayAddData, setTodayAddData] = useState<ItodayAdd | {}>({})
//@ts-ignore
const [orderInViewPort] = useInViewport(() => document.querySelector('#order'));
const [orderStatus, setOrderStatus] = useState({
hasGetData: false,
loading: false,
})
const [processingMembers, setProcessMembers] = useState<any>([]);
const [processingMemberLoading, setProcessingMemberLoading] = useState<boolean>(true)
// 交易与售后计数报表
const [tradeAndSold, setTradeAndSold] = useState({});
//@ts-ignore
const [tradeInViewPort] = useInViewport(() => document.querySelector('#trade'));
const [tradeStatus, setTradeStatus] = useState({
hasGetData: false,
loading: false,
})
// 商品计数报表
const [products, setProducts] = useState({});
//@ts-ignore
const [productInViewPort] = useInViewport(() => document.querySelector('#product'));
const [productStatus, setproductStatus] = useState({
hasGetData: false,
loading: false,
})
/**
* 顶部新增统计
......@@ -65,9 +86,60 @@ const Home: React.FC<{}> = () => {
}
})
}
}, [orderInViewPort])
/**
* 待处理会员
*/
useEffect(() => {
setProcessingMemberLoading(true);
PublicApi.getReportPlatformHomeGetMemberTally()
.then(({data, code}) => {
setProcessingMemberLoading(false)
if(code === 1000) {
setProcessMembers(data);
}
})
}, [])
/**
* /report/platform/home/getTradeAndAfterSaleTally
* 获取交易与售后计数报表
*/
useEffect(() => {
if(tradeInViewPort && !tradeStatus.hasGetData) {
setTradeStatus((state) => ({...state, loading: true }))
PublicApi.getReportPlatformHomeGetTradeAndAfterSaleTally()
.then(({data, code}) => {
setTradeStatus((state) => ({...state, loading: false, hasGetData: true }))
if(code === 1000) {
// setOrderData(data);
setTradeAndSold(data);
console.log(data);
}
})
}
}, [tradeInViewPort])
/**
* /report/platform/home/getCommodityTally
* 获取商品计数报表获取
*/
useEffect(() => {
if(productInViewPort && !productStatus.hasGetData) {
setproductStatus((state) => ({...state, loading: true }))
PublicApi.getReportPlatformHomeGetCommodityTally()
.then(({data, code}) => {
setproductStatus((state) => ({...state, loading: false, hasGetData: true }))
if(code === 1000) {
// setOrderData(data);
setProducts(data);
console.log(data);
}
})
}
}, [productInViewPort])
return (
// 全局统计
......@@ -94,15 +166,19 @@ const Home: React.FC<{}> = () => {
className={styles.sideListBox}
>
{
[1,2,3,4].map((item) => {
processingMemberLoading
? [1,2].map((item) => {
return <Skeleton active key={item}></Skeleton>
})
: processingMembers.map((item: any, key: number) => {
return (
<List.Item
key={item}
key={item.name}
actions={[<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>]}
>
<List.Item.Meta
title="15"
description={<><span className="commonStatusModify"></span>待提交审核</>}
title={item.count.toString()}
description={<><Badge status={PROCESS_STATUS[key]} text={item.name}></Badge></>}
/>
</List.Item>
)
......@@ -122,68 +198,57 @@ const Home: React.FC<{}> = () => {
</Row>
</Space>
{/* 订单统计 */}
<div id="trade">
<Space direction="vertical" style={{width:'100%', height: '100%'}} >
<Row gutter={[24, 12]}>
<Col span={6}>
<Row>
<Col span={24}>
<Card
headStyle={{borderBottom:'none'}}
title="待处理交易"
bordered={false}
>
<List
itemLayout="horizontal"
className={styles.sideListBox}
>
<List.Item
actions={[<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>]}
>
<List.Item.Meta
title="15"
description={<><span className="commonStatusModify"></span>待提交审核</>}
/>
</List.Item>
<List.Item
actions={[<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>]}
>
<List.Item.Meta
title="15"
description={<><span className="commonStatusModify"></span>待提交审核</>}
/>
</List.Item>
</List>
<Row gutter={[24, 12]} style={{display: 'flex', flexDirection: 'row'}}>
<Col span={6} style={{display: 'flex', flexDirection: 'column'}}>
<Row style={{height: '100%'}}>
{
tradeStatus.loading
? [1,2].map((item) => {
return (
<Col span={24} key={item} style={item == 1 ? { marginBottom: '18px'} : {}}>
<Card bordered={false}>
<Skeleton active />
</Card>
</Col>
<Col span={24} style={{marginTop: 26}}>
)
})
: Object.keys(tradeAndSold).map((item, key) => {
return (
<Col span={24} style={key == 1 ? { marginTop: '18px', flex: 1} : {}} key={item}>
<Card
headStyle={{borderBottom:'none'}}
title="待处理售后"
title={item === 'afterSaleList' ? '待处理售后' : '待处理交易'}
bordered={false}
style={{height: '100%'}}
>
<List
itemLayout="horizontal"
className={styles.sideListBox}
>
{
tradeAndSold[item].map((row) => {
return (
<List.Item
key={row.name}
actions={[<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>]}
>
<List.Item.Meta
title="15"
description={<><span className="commonStatusModify"></span>待提交审核</>}
/>
</List.Item>
<List.Item
actions={[<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>]}
>
<List.Item.Meta
title="15"
description={<><span className="commonStatusModify"></span>待提交审核</>}
title={row.count.toString()}
description={<><span className="commonStatusModify"></span>{row.name}</>}
/>
</List.Item>
)
})
}
</List>
</Card>
</Col>
)
})
}
</Row>
</Col>
<Col span={18}>
......@@ -193,11 +258,14 @@ const Home: React.FC<{}> = () => {
</Col>
</Row>
</Space>
</div>
{/* 商品品牌统计 */}
<div id="product">
<Space direction="vertical" style={{width:'100%'}}>
<StatisticsColumn />
<StatisticsColumn loading={productStatus.loading} data={products} />
</Space>
</div>
{/* 付款提现统计 */}
<Space direction="vertical" style={{width:'100%'}}>
<Settlement />
......
/*
* @Author: your name
* @Date: 2020-10-12 18:27:56
* @LastEditTime: 2020-10-13 10:01:23
* @Description: 附件
*/
import React from 'react';
import { Card } from 'antd';
import pdf_icon from '@/asserts/pdf_icon.png';
const styles = {
display: 'flex',
flexDirection: 'row',
alignItem: 'center',
color: '#00B37A',
backgroundColor: '#F4F5F7',
padding: '10px 10px',
cursor: 'pointer',
height: '100%'
}
const AppendixItem = (props) => {
return (
<div style={styles}>
<img src={pdf_icon} style={{width: '20px', marginRight: '15px'}} />
<div >{props.name}</div>
</div>
)
}
interface Iprops {
files: any[]
}
const Appendix: React.FC<Iprops> = (props) => {
const { files = [] } = props;
return (
<>
<Card title={"附件"} style={{height: '100%'}} bordered={false}>
{
files.map((item, key) => {
return (
<AppendixItem key={key} name={item.name} value={item.value}/>
)
})
}
</Card>
</>
)
}
export default Appendix;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Card, Col, Row, Select } from 'antd'
import { PublicApi } from '@/services/api';
const Option = Select.Option;
enum deliveryType {
logistics,
bySelf
}
interface Iprops {
deliveryDate: string,
deliveryType: deliveryType,
receiveAddress: string,
receiveUserName: string,
receiveUserTel: string
deliveryAddress: string,
deliveryUserName: string,
deliveryUserTel: string,
editDeliverAddress: boolean,
deliverAddressOnChange?: (value: string) => void,
activeAddress?: string,
deliverAddressOption?: {label: string, value: string}[]
}
const DeliveryInfomation: React.FC<Iprops> = (props) => {
return (
<Card title="交付信息">
<Row>
<Col span={6}>
{/* <OtherRequirement /> */}
<Row style={{marginBottom: '20px'}}>
<Col span={6}>配送方式</Col>
<Col>{props.deliveryType == 1 ? '物流' : '自提'}</Col>
</Row>
<Row>
<Col span={6}>交期</Col>
<Col>{props.deliveryDate}</Col>
</Row>
</Col>
<Col span={9} style={props.deliveryType == 1 ? {} : {display: 'none'}}>
<Row style={{marginBottom: '20px'}}>
<Col span={5}>收货地址</Col>
<Col>{props.receiveUserName} / {props.receiveUserTel}</Col>
</Row>
<Row>
<Col offset={5}>{props.receiveAddress}</Col>
</Row>
</Col>
{
props.editDeliverAddress
? <Col span={9}>
<Row style={{marginBottom: '20px'}}>
<Col span={5}>发货地址</Col>
<Col span={19}>
<Select style={{width: '100%'}} value={props.activeAddress}>
{
props.deliverAddressOption.map((item) => {
return (
<Option key={item.value} value={item.value}>
{item.label}
</Option>
)
})
}
{/* <Option value={"1"}>test</Option> */}
</Select>
</Col>
</Row>
</Col>
: <Col span={9} style={!props.deliveryUserName ? {display: 'none'} : {}}>
<Row style={{marginBottom: '20px'}}>
<Col span={5}>发货地址</Col>
<Col>{props.deliveryUserTel} / {props.deliveryUserName}</Col>
</Row>
<Row>
<Col offset={5}>{props.deliveryAddress}</Col>
</Row>
</Col>
}
</Row>
</Card>
)
}
export default DeliveryInfomation;
\ No newline at end of file
import React from 'react';
import { Card, Row, Col } from 'antd';
interface Iexpain {
[key: string]: string
}
interface Iprops {
explain: Iexpain[]
}
const OtherRequirement: React.FC<Iprops> = (props) => {
const { explain = [] } = props;
return (
<Card title="其他要求">
{
[0,1,2].map((item) => {
return (
<Row style={{marginBottom: '15px'}} key={item}>
{
explain.slice(item * 2, item * 2 + 2).map((i) => {
return (
<React.Fragment key={i.name} >
<Col span={3}>{i.name}</Col>
<Col span={8}>{i.value}</Col>
</React.Fragment>
)
})
}
</Row>
)
})
}
</Card>
)
}
export default OtherRequirement;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Button, Drawer } from 'antd';
import Content from './content';
import { PublicApi } from '@/services/api'
import { createFormActions } from '@formily/antd'
const actions = createFormActions();
interface Iprops {
type: string, // veiw | edit,
id: string,
brand: string,
category: string,
name: string,
productProps: any[],
files: IfileProps[],
unitName: string,
quantity?: string,
processUnitPrice?: string
}
interface IfileProps {
name: string,
url: string
}
const DrawerProcessDetail: React.FC<Iprops> = (props) => {
const { id, brand, category, name, productProps, files, unitName, quantity, processUnitPrice} = props;
const [visible, setVisible] = useState<boolean>(false);
const onClose = () => {
setVisible(false)
}
const onOpen = () => {
setVisible(true)
}
return (
<>
<div onClick={onOpen}>
{props.children}
</div>
<Drawer
title="查看加工明细"
width={720}
onClose={onClose}
visible={visible}
bodyStyle={{ padding: '0'}}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={onClose} style={{ marginRight: 8 }}>
取消
</Button>
<Button onClick={onClose} type="primary">
确认
</Button>
</div>
}
>
<Content
name={name}
id={id}
brand={brand}
category={category}
unitName={unitName}
productProps={productProps}
quantity={quantity}
processUnitPrice={processUnitPrice}
type={"detail"}
files={files}
actions={actions}
/>
</Drawer>
</>
)
}
export default DrawerProcessDetail;
\ No newline at end of file
.container {
display: flex;
flex-direction: row;
height: 100%;
.menu {
flex-basis: 159px;
display: flex;
flex-direction: column;
justify-content: start;
height: 100%;
.menuItem {
font-size: 12px;
font-weight: 500;
color: #303133;
line-height: 12px;
padding: 10px 24px;
margin-bottom: 15px;
cursor: pointer;
}
.active {
border-left: 2px solid #00B37A;
}
}
.body {
flex: 1;
display: flex;
flex-direction: column;
border-left: 1px solid #EEF0F3;
overflow: scroll;
overflow-x: hidden;
.common {
padding: 24px 24px 0 24px;
.header {
border-left: 2px solid #00B37A;
color: #606266;
padding: 0 10px;
margin-bottom: 24px;
font-size: 14px;
}
.info {
.infoRow {
margin-bottom: 24px;
.label {
color: #909399;
}
}
}
}
}
}
\ No newline at end of file
import React, { useState, useRef, useEffect } from 'react';
import styles from './content.less';
import { Row, Col, Anchor } from 'antd';
import classnames from 'classnames';
// import {FileList, UploadFile} from '../../components/UploadFile';
import Appendix from '../Appendix';
import NiceForm from '@/components/NiceForm';
export interface IMenu {
name: string,
value: number
}
const Content = (props) => {
const { id, name, category, brand, unitName, files, productProps, quantity, processUnitPrice } = props;
const [active, setActive] = useState<string>("基本信息");
const [menu, setMenu] = useState<IMenu[]>([])
const ref = useRef<any>(null);
const getMenuItemCs = (name: string) => {
return classnames({
[styles.menuItem]: true,
[styles.active]: name === active
})
}
const activeAndScroll = (item) => {
setActive(item.name);
ref.current.scrollTop = item.value;
}
useEffect(() => {
const basic = [{name: '基本信息', value: 0}]; // 238
let height = 238;
let flag = false;
const attributes = productProps && productProps.map((item) => {
const prevHeight = height;
height = height + 112;
flag = true;
return {
name: item.customerAttribute?.name || item.name,
value: prevHeight
}
}) || [];
const files = [{name: '附件', value: flag ? height : height - 112}];
height += 130;
const progress = [{name: '加工要求', value: height}];
setMenu(basic.concat(attributes, files, progress));
}, [productProps])
return (
<div className={styles.container}>
<div className={styles.menu}>
{
menu.map((item,key) => {
return (
<div key={item.name} className={getMenuItemCs(item.name)} onClick={() => activeAndScroll(item)}>
{item.name}
</div>
)
})
}
</div>
<div className={styles.body} ref={ref}>
<div className={styles.common} >
<div className={styles.header}>{"基本信息"}</div>
<div className={styles.info}>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>商品ID</Col>
<Col span={12}>{id}</Col>
</Row>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>商品名称</Col>
<Col span={12}>{name}</Col>
</Row>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>商品品类</Col>
<Col span={12}> {category}</Col>
</Row>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>商品品牌</Col>
<Col span={12}>{brand}</Col>
</Row>
</div>
</div>
{
productProps && productProps.map((item, key) => {
return (
<div className={styles.common} key={key}>
<div className={styles.header}>{item.name}</div>
<div className={styles.info}>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>{item.name}</Col>
<Col span={12}>{item.value}</Col>
</Row>
</div>
</div>
)
})
}
<div className={styles.common} id="附件" >
<div className={styles.header}>{"附件"}</div>
<div className={styles.info}>
{
files.length === 0
? <p></p>
: <Appendix files={files} />
}
</div>
</div>
<div className={styles.common} >
<div className={styles.header}>{"加工"}</div>
<div className={styles.info}>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>单位</Col>
<Col span={12}>{unitName}</Col>
</Row>
</div>
<div className={styles.info}>
<>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>加工数量</Col>
<Col span={12}>{quantity}</Col>
</Row>
<Row className={styles.infoRow}>
<Col className={styles.label} span={4}>加工单价</Col>
<Col span={12}>{processUnitPrice}</Col>
</Row>
</>
</div>
</div>
</div>
</div>
)
}
export default Content;
\ No newline at end of file
import React from 'react';
import { Card, Steps } from 'antd';
const Step = Steps.Step;
const customDot = (dot, { status, index }) => (
<span>
{dot}
</span>
);
interface Istatus {
isExecute: number,
roleName: string,
step: number,
taskName: string
}
interface Iprops {
outerTaskList: Istatus[]
}
const StatusStep: React.FC<Iprops> = (props) => {
const {outerTaskList = []} = props;
return (
<div style={{padding: '16px 0'}}>
<h1 >外部状态</h1>
<Steps progressDot={customDot} style={{marginTop: '20px'}}>
{
outerTaskList.map((item: Istatus) => {
return (
<Step title={item.taskName} status={item.isExecute == 1 ? 'finish' : 'wait'} description={item.roleName} key={item.step} />
)
})
}
</Steps>
</div>
)
}
export default StatusStep
\ No newline at end of file
import React from 'react';
import moment from 'moment';
import DrawerProcessDetail from '../components/ProcessDetail/DrawerProcessDetail';
import { ColumnsType } from 'antd/es/table';
/**
* 通知单明细
*/
export const columns: ColumnsType<any> = [
{
title: '订单号',
dataIndex: 'orderNo',
},
{
title: 'ID',
dataIndex: 'id',
},
{
title: '商品名称',
dataIndex: 'productName',
},
{
title: '品类',
dataIndex: 'category',
},
{
title: '品牌',
dataIndex: 'brand',
},
{
title: '单位',
dataIndex: 'unit',
},
{
title: '订单数量',
dataIndex: 'purchaseCount'
},
{
title: '加工数量',
dataIndex: 'processNum',
},
{
title: '加工单价',
dataIndex: 'processPrice',
},
{
title: '加工费',
dataIndex: 'processTotalPrice',
},
{
title: '交期',
dataIndex: 'deliveryDate',
render: (text, record) => {
return moment(text).format('YYYY-MM-DD');
}
},
{
title: '操作',
dataIndex: 'action',
render: (text, record: any) => {
return (
<DrawerProcessDetail
type="view"
id={record.productId}
brand={record.brand}
category={record.category}
name={record.productName}
productProps={record.property.specs}
files={record.property.annex}
unitName={record.unit}
quantity={record.processNum}
processUnitPrice={record.processPrice}
>
<a>查看加工明细</a>
</DrawerProcessDetail>
)
}
},
];
/**
* 通知单明细
*/
const orderFilterList = ["订单号", "订单数量"]
export const orderDetailColumn = columns.filter((item) => !orderFilterList.includes(item.title.toString()));
/**
* 外部工作流记录
*/
export const innerWorkFlowRecordColumn: ColumnsType<any> = [
{
title: '流转记录',
dataIndex: 'id'
},
{
title: '操作人',
dataIndex: 'operator',
},
{
title: '部门',
dataIndex: 'department'
},
{
title: '职位',
dataIndex: 'jobTitle'
},
{
title: '状态',
dataIndex: 'status'
},
{
title: '操作',
dataIndex: 'operate'
},
{
title: '操作时间',
dataIndex: 'operateTime',
render: (text, record) => {
return moment(text).format('YYYY-MM-DD HH:mm:ss')
}
},
{
title: '审核意见',
dataIndex: 'opinion'
}
]
/**
* 内部流转
*/
export const outerWorkflowRecordsColumn: ColumnsType<any> = [
{
title: '流转顺序号',
dataIndex: 'id'
},
{
title: '操作角色',
dataIndex: 'roleId',
},
{
title: '状态',
dataIndex: 'roleName'
},
{
title: '操作',
dataIndex: 'operate'
},
{
title: '操作时间',
dataIndex: 'operateTime'
},
{
title: '审核意见',
dataIndex: 'opinion'
}
]
/**
* 生产通知单收货统计
*/
export const receiveColumns: ColumnsType<any> = [
{
title: '订单号',
dataIndex: 'orderNo',
},
{
title: 'ID',
dataIndex: 'id',
},
{
title: '商品名称',
dataIndex: 'productName',
},
{
title: '品类',
dataIndex: 'category',
},
{
title: '品牌',
dataIndex: 'brand',
},
{
title: '单位',
dataIndex: 'unit',
},
{
title: '加工数量',
dataIndex: 'processNum',
},
{
title: '加工单价',
dataIndex: 'processPrice',
},
{
title: '加工费',
dataIndex: 'processTotalPrice',
},
{
title: '交期',
dataIndex: 'deliveryDate',
render: (text, record) => {
return moment(text).format('YYYY-MM-DD');
}
},
{
title: '已发货',
dataIndex: 'deliverNum'
},
{
title: '已收货',
dataIndex: 'receiveNum'
},
{
title: '差异数量',
dataIndex: 'differenceNum'
},
{
title: '未发货',
dataIndex: 'notDeliverNum'
}
];
\ No newline at end of file
import React, {useState, useEffect, useCallback} from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import AvatarWrap from '@/components/AvatarWrap';
import { PageHeader, Descriptions, Card, Tabs, Row, Col, Spin, Badge, Table } from 'antd';
import StatusStep from '../components/StatusStep';
import OtherRequirement from '../components/OtherRequirement';
import Appendix from '../components/Appendix';
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api';
import StatusTag from '@/components/StatusTag';
import DeliveryInfomation from '../components/DeliveryInformation';
import moment from 'moment';
import { columns, orderDetailColumn, innerWorkFlowRecordColumn, outerWorkflowRecordsColumn, receiveColumns } from './columns';
export const COLOR = [
"red", // 不接受申请
"#d9d9d9", // 待提交申请,
"yellow", // 待审核
"red", // 审核不通过
"green", // 审核通过
"blue", // 待新增加工发货单
"orange", // 待审核加工发货单
"cyan", // 待新增物流单
"geekblue", // 待确认物流单
"gold", // 待确认发货,
"green", // 已确认发货
"orange", //待确认回单
"green", // 完成
]
export const STATUS = [
"default",
"default",
"warning",
"primary",
"danger",
"success"
]
const { TabPane } = Tabs;
const Detail: React.FC<{}> = () => {
const [info, setInfo] = useState<any>({})
const { id } = usePageStatus();
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
if(id) {
setLoading(true)
const service = PublicApi.getEnhancePlatformAllDetails;
service && service({id: id})
.then(({data, code}) => {
if(code === 1000) {
setInfo(data);
}
}).finally(() => {
setLoading(false)
})
}
}, [id]);
return (
<Spin spinning={loading}>
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
name: "通知单号:"
}}
extra={(
<span style={{ fontSize: 12, fontWeight: 'normal' }}>{info?.noticeNo}</span>
)}
/>
}
>
<Row>
<Col span={22}>
<Descriptions
column={3}
style={{padding: '0 32px', fontWeight: 400}}
colon={false}
>
<Descriptions.Item label="通知单摘要:">{info?.summary}</Descriptions.Item>
<Descriptions.Item label="加工企业:">{info?.processName}</Descriptions.Item>
<Descriptions.Item label="单据时间:">{info && info.createTime && moment(info.createTime).format('YYYY-MM-DD') || null }</Descriptions.Item>
<Descriptions.Item label="通知单来源:">{info?.source == '1' ? '订单加工': '商品加工'}</Descriptions.Item>
<Descriptions.Item label="外部状态:">
<StatusTag type={STATUS[info.outerStatus] || ''} title={info.outerStatusName} />
</Descriptions.Item>
<Descriptions.Item label="内部状态:">
<Badge
color={COLOR[info.innerStatus] || 'success'}
text={info.innerStatusName}></Badge>
</Descriptions.Item>
</Descriptions>
</Col>
</Row>
</PageHeader>
</>
}
>
<Card bodyStyle={{padding: '5px 24px 15px 24px'}}>
<StatusStep outerTaskList={info?.outerTaskList}/>
</Card>
<div style={{marginTop: '20px'}}>
<Card>
<h1 style={{fontSize: '14px', marginBottom: '16px'}}>通知单明细</h1>
<Table dataSource={info?.details} columns={info.source === 2 ? orderDetailColumn : columns}/>
</Card>
</div>
<div style={{marginTop: '20px', display: info.pnoReceiveDeliverDetailDOList?.length > 0 ? 'block' : 'none'}}>
<Card bodyStyle={{padding: '10px 24px 24px 24px'}}>
<Tabs>
<TabPane tab="收发货统计" key="1">
<Table columns={receiveColumns} dataSource={info?.details} />
</TabPane>
<TabPane tab="收发货明细" key="2">
<Table dataSource={[]} />
</TabPane>
</Tabs>
</Card>
</div>
<div style={{marginTop: '20px'}}>
<DeliveryInfomation
deliveryDate={info.deliveryDate}
deliveryType={info.deliveryType}
receiveAddress={info.receiveAddress}
receiveUserName={info.receiveUserName}
receiveUserTel={info.receiveUserTel}
deliveryAddress={info.deliveryAddress}
deliveryUserName={info.deliveryUserName}
deliveryUserTel={info.deliveryUserTel}
editDeliverAddress={false}
/>
</div>
<div style={{marginTop: '20px'}}>
<Row justify="space-between">
<Col flex={4}>
<OtherRequirement explain={info.otherAsk?.explain} />
</Col>
<Col flex={2} style={{marginLeft: '20px'}} >
<Appendix files={info.otherAsk?.annex}/>
</Col>
</Row>
</div>
<div style={{marginTop: '20px'}} >
<Card bodyStyle={{padding: '10px 24px 24px 24px'}}>
<Tabs>
<TabPane tab="外部流转记录" key="1">
<Table
columns={outerWorkflowRecordsColumn}
dataSource={info.outerWorkflowRecordsList}
/>
</TabPane>
<TabPane tab="内部流转记录" key="2">
<Table
columns={innerWorkFlowRecordColumn}
dataSource={info.innerWorkflowRecordsList}
/>
</TabPane>
</Tabs>
</Card>
</div>
{/* <ProcessDetail /> */}
</PageHeaderWrapper>
</Spin>
)
}
export default Detail
\ No newline at end of file
import React, { Component, useRef, useCallback } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Card } from 'antd';
import { StandardTable } from 'god';
import { createFormActions } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import NiceForm from '@/components/NiceForm';
import { ColumnsType } from 'antd/es/table';
import { timeRange } from '@/utils'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { PublicApi } from '@/services/api';
import { querySchema } from './schema';
import EyePreview from '@/components/EyePreview';
import moment from 'moment';
import StatusTag from '@/components/StatusTag';
interface IProps {}
export const SUPPLIER_OUTER_STATUS_COLOR = [
"default",
"default",
"primary",
"warning",
"danger",
"success"
]
const columns: ColumnsType<any> = [
{
title: '通知单号',
dataIndex: 'noticeNo',
render: (text, record) => {
const url = '/productionNoticeManage/productionNotice/detail';
return (
<EyePreview url={url + `?id=${record.id}`}>{text}</EyePreview>
)
}
},
{ title: '通知单摘要', dataIndex: 'summary' },
{ title: '供应会员', dataIndex: 'supplierName' },
{ title: '加工企业名称', dataIndex: 'processName'},
{
title: '单据时间',
dataIndex: 'createTime',
render: (text, record) => {
return moment(text).format('YYYY-MM-DD HH:mm:ss')
}
},
{
title: '外部状态',
dataIndex: 'outerStatusName',
render: (text, record) => {
return <StatusTag type={SUPPLIER_OUTER_STATUS_COLOR[record.outerStatus]} title={text}></StatusTag>
}
},
]
const formActions = createFormActions();
const Query: React.FC<IProps> = () => {
const ref = useRef<any>({});
/**
* 查询
* @params values 表单字段
*/
const handleSearch = useCallback((values: any) => {
const {docTime, ...rest} = values;
const {st, et} = timeRange(docTime);
let searchData = {
...rest,
startTime: st,
endTtime: et
}
ref.current.reload(searchData)
}, [])
// 初始化高级筛选选项
const fetchSelectOptions = async () => {
return {};
};
const fetchData = useCallback(async (params: any) => {
const service = PublicApi.getEnhancePlatformAllList;
const res = await service(params);
return res.data
}, []);
return (
<PageHeaderWrapper
title={'生产通知单查询'}
>
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
controlRender={
<NiceForm
actions={formActions}
// expressionScope={{controllerBtns: controllerBtns(), batchUpdateBtn: batchUpdateBtn()}}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'noticeNo', FORM_FILTER_PATH);
useAsyncInitSelect(
['outerStatus'],
fetchSelectOptions,
);
}}
schema={querySchema}
/>
}
/>
</Card>
</PageHeaderWrapper>
)
}
export default Query
\ No newline at end of file
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
export const commonTimeList = [
{ label: '今天', value: 1},
{ label: '一周内', value: 2},
{ label: '一个月内', value: 3},
{ label: '三个月内', value: 4},
{ label: '六个月内', value: 5},
{ label: '一年内', value: 6 },
{ label: '一年前', value: 7}
];
/**
* 单据时间
*/
export const docTime = [{label: '单据时间(全部)', value: 0}].concat(commonTimeList);
/**
* @author: Bill
* @description: 指派生产通知单查询页 schema - 生产通知单查询
*/
export const querySchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
noticeNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
tip: '输入通知单号进行搜索',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
memberName: {
type: 'string',
'x-component-props': {
placeholder: '加工企业名',
allowClear: true,
},
},
docTime: {
type: 'string',
default: 0,
enum: docTime,
'x-component-props': {
placeholder: '单据时间(全部)',
allowClear: true,
},
},
outerStatus: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '外部状态(全部)',
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
......@@ -9,6 +9,7 @@ import * as SearchApi from './SearchApi'
import * as OrderApi from './OrderApi';
import * as SettleApi from './SettleApi';
import * as ReportApi from './reportApi';
import * as EnhanceApi from './enhanceApi';
/**
* 可在这里写入自定义的接口
......@@ -29,5 +30,6 @@ export const PublicApi = {
...SearchApi,
...OrderApi,
...SettleApi,
...ReportApi
...ReportApi,
...EnhanceApi
}
......@@ -10,6 +10,7 @@ const tokenList = [
{ name: 'Order', token: '5de0aaeaac12c8d911d86dada6cd128993e34cd6e13135fa79246aa5979a2bcd' }, //订单服务,
{ name: 'Settle', token: 'fffbeeaaa198c285955997c606bc279fc6950fea118580c786f2c73eecccaa6a' }, //结算服务
{ name: 'report', token: 'e709e5bd31eb2b84de468944b153a62a05afcc13f0ea880be7333b928c7c0620'}, //报表服务
{ name: 'enhance', token: '594a7e7ff17f6f40fb9fb726c1da9a3f282a926a8d386eb6cbfd668a3f75f251' } // 加工服务
]
const getConfigMap = (tokens) => tokens.map(v => ({
......
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