Commit a1bd8ef1 authored by Bill's avatar Bill

refactor: 重构加工

parent eb1c4aa8
import moment from 'moment';
import React from 'react';
import { ORDER_TYPE } from '@/constants/order'
export const orderColumns = [
{
title: '订单号/摘要',
dataIndex: 'orderNoAndDesc',
render: (text, record) => {
return (
<div>
<p>{record.orderNo}</p>
<p>{record.orderThe}</p>
</div>
)
}
},
{
title: "采购会员",
dataIndex: 'memberName'
},
{
title: '下单时间',
dataIndex: 'createTime',
render: (text) => moment(text).format('YYYY-MM-DD HH:mm:ss')
},
{
title: '订单状态',
dataIndex: 'externalStateName',
},
{
title: '订单类型',
dataIndex: 'type',
render: (text, record) => {
// :1.询价采购2.需求采购3.现货采购4.集采5.渠道直采6.渠道现货7.积分兑换8.渠道积分兑换
return (
<span>{ORDER_TYPE[text] || ''}</span>
)
}
}
]
export const orderProductColumns = [
{
title: '商品ID/名称',
dataIndex: 'id'
},
{
title: '品类',
dataIndex: 'category',
},
{
title: '品牌',
dataIndex: 'brand'
},
{
title: '单位',
dataIndex: 'unit'
},
{
title: '订单数量',
dataIndex: 'purchaseCount'
},
{
title: '剩余加工数量',
dataIndex: 'restNum',
render: (text, record) => +record.purchaseCount - (+record.processNum || 0)
},
{
title: '已加工数量',
dataIndex: 'processNum',
render: (text) => text || 0
}
]
/**
* 加工商品schema
*/
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { ISchema } from '@formily/antd';
export const orderSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
name: {
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,
columns: 3,
},
properties: {
customerCategoryId: {
type: 'string',
'x-component': 'Cascader',
'x-component-props': {
placeholder: '请选择商品品类',
allowClear:true,
style: {
width: '160px',
// margin: '0 20px 0 0'
},
fieldNames: { label: 'title', value: 'id', children: 'children' }
}
},
brandId: {
type: 'string',
// 'x-component': 'Select',
enum: [],
'x-component-props': {
placeholder: '请选择商品品牌',
allowClear:true,
showSearch: true,
optionFilterProp: "children",
}
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
import React, { useMemo } from 'react';
import {
SchemaMarkupField as Field,
} from '@formily/antd'
import { Row, Col } from 'antd';
type ValueType = {
name: string,
value: string | number
}
interface Iprops {
value: ValueType[],
}
const FormilyProductAttrsLayout: React.FC<Iprops> & { isFieldComponent: boolean } = (props: Iprops) => {
const { value } = props;
const titleStyle = useMemo(() => {
return {
paddingLeft: '8px',
marginBottom: '24px',
lineHeight: '14px',
fontSize: '14px',
fontWeight: 500,
borderLeft: '2px solid #00B37A',
}
}, [])
const cacheValue = useMemo(() => value, [value])
return (
<>
{
cacheValue?.map((item, key) => {
return (
<div key={key} style={key < value.length - 1 ? {marginBottom: '24px'} : {}}>
<div style={titleStyle}>{item.name}</div>
<Row>
<Col span={4} style={{color: '#909399'}}>{item.name}</Col>
<Col span={18}>{item.value}</Col>
</Row>
</div>
)
})
}
</>
)
}
FormilyProductAttrsLayout.isFieldComponent = true;
export default FormilyProductAttrsLayout
.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: 18px 0px;
cursor: pointer;
// border-left: 2px solid transparent;
transition: all 0.2s ease-in-out;
.menuTitle {
border-left: 2px solid transparent;
padding-left: 16px;
}
.active {
color: #303133;
border-left: 2px solid #00B37A;
}
}
}
.body {
flex: 1;
display: flex;
flex-direction: column;
border-left: 1px solid #EEF0F3;
overflow: scroll;
overflow-x: hidden;
padding: 12px;
// .common {
// padding: 24px 24px 0 16px;
// .header {
// border-left: 2px solid #00B37A;
// color: #606266;
// padding: 0 10px;
// line-height: 14px;
// margin-bottom: 24px;
// font-size: 14px;
// // &:before {
// // content: '';
// // display: inline-block;
// // height: 8px;
// // width: 2px;
// // background-color: #00B37A;
// // }
// }
// .info {
// .infoRow {
// margin-bottom: 24px;
// .label {
// color: #909399;
// }
// }
// }
// }
}
}
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Drawer, Row, Col, Space, Button } from 'antd'
import { useScroll } from '@umijs/hooks';
import styles from './index.less';
// import useGetClientRect from './useGetClientRect';
import { createFormActions, FormEffectHooks, registerVirtualBox } from '@formily/antd';
import classnames from 'classnames'
import NiceForm from '@/components/NiceForm';
import schema from './schema';
import FormilyProductAttrsLayout from './formilyProductAttrsLayout';
const formActions = createFormActions();
/**
* 查看加工明细
*/
/** 查看或编辑 加工商品, 商品的属性 */
export type productInfo = {
/** 当加工订单时,拥有id 唯一 */
id?: number,
/** 当加工订单时,拥有orderid 订单id */
orderId?: number,
/** 当加工订单时,拥有orderNo 订单👌 */
orderNo?: number
/** skuid 属于唯一值 */
skuid: number,
commodityId: number,
/** 商品名 */
name: string,
/** 品类 */
category: string,
/** 品牌 */
brand: string,
/** 单位 */
unitName: string,
/** 含税跟税率合在一起的文字显示 */
isHasTaxAndTaxRate?: string,
/** 是否含税 */
isHasTax?: 0 | 1,
/** 税率 */
taxRate?: string,
/** 加工数量 */
processNum?: string,
/** 加工单价 */
processUnitPrice?: string,
/** 加工数量 * 加工单价 */
processTotalPrice?: number,
/** 附件 */
enclosure?: {
name: string,
url: string
}[],
/** 商品属性 */
productProps: {
name: string,
value: string
}[]
}
interface Iprops {
visible: boolean,
onClose?: (() => void) | null,
onSubmit?: ((values: any) => void) | null,
/**
* 当前商品值
*/
value: productInfo
// dataProps: DataPropsType
}
/**
* 修改商品 提交数据
*/
export type productSubmitType = {
/** 当加工订单时,拥有id 唯一 */
id?: number,
/** 当加工订单时,拥有orderid 订单id */
orderId?: number,
/** 当加工订单时,拥有orderNo 订单👌 */
orderNo?: number
/** skuid, 用这个去判断工作流 */
skuid: number,
commodityId: number,
brand: string,
category: string,
/** 商品名 */
name: string,
enclosure: {
name: string,
url: string,
status: "done"
type: "image/jpeg"
}[],
/** 是否含税 */
isHasTax: (0 | 1) & number,
/** 税率 */
taxRate: string,
/** 加工数量 */
processNum: string,
/** 商品属性 */
productProps: { name: string, value: string }[],
unitName: string,
/** 加工单价 */
processUnitPrice: string,
}
const ProductDrawer: React.FC<Iprops> = (props: Iprops) => {
const { visible, onClose, onSubmit, value } = props;
const [scroll, ref] = useScroll<HTMLDivElement>();
const [menu, setMenu] = useState<string[]>([])
const [rangeHeight, setRangeHeight] = useState<number[]>([])
const [activeIndex, setActiveIndex] = useState<number>(0);
const activeAndScroll = (index: number) => {
setActiveIndex(index);
ref.current.scrollTop = rangeHeight[index]
}
/**
* @tofix 这里有个bug,就是上面点击了之后,然后滚动,然后再做了一次计算,会有问题
*/
useEffect(() => {
const { top } = scroll;
let activeKey = 0;
for (let i = 0; i < rangeHeight.length - 1; i++) {
if (top >= rangeHeight[i] && top < rangeHeight[i + 1]) {
activeKey = i;
break;
}
activeKey = i + 1;
}
// console.log(activeKey)
setActiveIndex(activeKey)
}, [scroll])
useEffect(() => {
if (!visible) {
return;
}
const childNodes = ref.current.childNodes;
if (!childNodes) {
return
}
const formNode = childNodes[0].childNodes[0].childNodes[0].childNodes
const menuData = [];
let sum = 0;
const ranges = [0];
formNode.forEach((_item) => {
const { title, offsetHeight } = getMenuAndHeight(_item);
if ((_item as any).className.includes("ant-row")) {
const attributes = _item.childNodes[0].childNodes[0].childNodes[0].childNodes;
attributes.forEach((_row) => {
const { title, offsetHeight } = getMenuAndHeight(_row);
saveRangeAndMenuData(menuData, ranges, title, sum += offsetHeight);
})
return;
}
saveRangeAndMenuData(menuData, ranges, title, sum += offsetHeight);
})
setMenu(menuData.filter(Boolean));
setRangeHeight(ranges);
}, [visible, ref])
const getMenuAndHeight = (node) => {
const title = (node.firstChild as any)?.innerText || ''
const offsetHeight = (node as any).offsetHeight;
return { title, offsetHeight }
}
const saveRangeAndMenuData = (menuData: string[], ranges: number[], title: string, resultHeight: number) => {
menuData.push(title)
// sum += offsetHeight;
ranges.push(resultHeight);
}
const handleConfirm = () => {
formActions.submit()
}
const handleSubmit = (values: productSubmitType) => {
onSubmit?.(values)
}
return (
<Drawer
visible={visible}
onClose={onClose}
width={800}
title="查看加工明细"
bodyStyle={{padding: '0px'}}
footer={
(
<div style={{display: 'flex', flexDirection: 'row', justifyContent: 'flex-end'}} >
<Space>
<Button onClick={onClose}>取消</Button>
<Button type="primary" onClick={handleConfirm}>确认</Button>
</Space>
</div>
)
}
>
<div className={styles.container}>
<div className={styles.menu}>
{
menu.map((item,key) => {
return (
<div key={item} className={classnames(styles.menuItem)} onClick={() => activeAndScroll(key)}>
<span className={classnames(styles.menuTitle, { [styles.active]: activeIndex === key })} >
{item}
</span>
</div>
)
})
}
</div>
<div className={styles.body} ref={ref}>
<NiceForm
value={value}
schema={schema}
components={{
FormilyProductAttrsLayout
}}
actions={formActions}
onSubmit={handleSubmit}
/>
</div>
</div>
</Drawer>
)
}
export default ProductDrawer
import { ISchema } from '@formily/antd';
const schema: ISchema = {
type: 'object',
properties: {
basicInfo: {
type: 'string',
'x-component': 'FlagBox',
"x-component-props": {
title: '单据审核',
},
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 18,
labelAlign: 'left',
},
properties: {
skuid: {
type: 'string',
title: 'skuId',
display: false,
},
commodityId: {
type: 'string',
title: '商品id',
editable: false,
},
name: {
title: "商品名称",
type: 'string',
editable: false,
},
category: {
title: "商品品类",
type: 'string',
editable: false,
},
brand: {
title: '商品品牌',
type: 'string',
editable: false,
},
},
},
}
},
productProps: {
type: 'string',
'x-component': 'formilyProductAttrsLayout'
},
files: {
type: 'string',
'x-component': 'FlagBox',
"x-component-props": {
title: '附件',
},
properties: {
enclosure: {
'x-component': 'FormilyUploadFiles'
}
}
},
processRequire: {
type: 'string',
'x-component': 'FlagBox',
"x-component-props": {
title: '加工要求',
},
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 18,
labelAlign: 'left',
},
properties: {
unitName: {
type: 'string',
title: '单位',
editable: false,
},
processNum: {
type: 'string',
title: '加工数量',
},
processUnitPrice: {
title: "单价",
type: 'string'
},
isHasTax: {
title: "是否含税",
type: 'radio',
enum: [
{
label: '是',
value: 1,
},
{
label: '否',
value: 0,
}
]
},
taxRate: {
title: '税率',
type: 'string'
},
},
},
}
}
}
}
export default schema
import React from 'react'
interface Iprops {
value: any,
props: {
'x-component-props': {
isImage?: boolean,
[key: string]: any
}
}
}
const ReadOnly: React.FC<Iprops> & { isFieldComponent: boolean } = (props: Iprops) => {
const { value } = props;
const componentProps = props.props?.['x-component-props'] || {}
return (
<>
{
value && componentProps?.isImage && (
<img src={value} style={{width: '32px', height: '32px'}} />
) || (
<div>{value}</div>
)
}
</>
)
}
ReadOnly.isFieldComponent = true
export default ReadOnly
import React from 'react'
import { connect, IConnectProps, MergedFieldComponentProps, registerFormField } from '@formily/antd'
import { Input } from 'antd'
const PreviewText = ({ value }: { value: string | number }) => {
return (
<span>{value}</span>
)
}
export const mapTextComponent = (
Target: React.JSXElementConstructor<any>,
props: any = {},
fieldProps: any = {}
): React.JSXElementConstructor<any> => {
const { editable } = fieldProps
// console.log("props", props, "fieldProps", fieldProps);
if (editable !== undefined) {
if (editable === false) {
return PreviewText
}
}
return Target
}
export const mapStyledProps = (
props: IConnectProps,
fieldProps: MergedFieldComponentProps
) => {
const { loading, errors } = fieldProps
if (loading) {
props.state = props.state || 'loading'
} else if (errors && errors.length) {
props.state = 'error'
}
}
export default connect({
// getProps: mapStyledProps, //处理状态映射
getComponent: mapTextComponent //处理详情态
})((props) => {
const { dataSource, value, onChange } = props;
return <Input value={value} onChange={onChange} />
})
import React, { useCallback, useMemo, useState } from 'react';
import { history } from 'umi';
import ReutrnEle from '@/components/ReturnEle';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Button, Cascader } from 'antd';
import { Button, Cascader, message, Space, Table } from 'antd';
import { LinkOutlined, PlusOutlined, SaveOutlined } from '@ant-design/icons';
import NiceForm from '@/components/NiceForm';
import creataSchema from './schema';
......@@ -10,7 +7,7 @@ import { createFormActions, FormEffectHooks, registerVirtualBox } from '@formily
import MellowCard from '@/components/MellowCard';
import AnchorPage from '@/layouts/AnchorPage';
import { ArrayTable } from '@formily/antd-components'
import ReadOnlyInput from './components/ReadOnlyInput';
import ReadOnly from './components/ReadOnly';
import FormilyUploadFiles from '@/components/UploadFiles/FormilyUploadFiles';
import { CloudUploadOutlined } from '@ant-design/icons'
import TableModal from '@/pages/member/components/TableModal';
......@@ -26,11 +23,17 @@ import { GetMemberManageLowerPageBynameroleResponse, GetMemberManageRoleSubListR
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { getAuth } from '@/utils/auth';
import { ColumnsType } from 'antd/es/table';
import { GetProductCommodityCommonGetCommodityListByBuyerResponseDetail } from '@/services/ProductV2Api';
import ProductDrawer, { productSubmitType, productInfo } from './components/ProductDrawer';
import { priceFormat } from '@/utils/numberFomat';
import { orderColumns, orderProductColumns } from './common/columns/orderColumn';
import { orderSchema } from './common/schemas/orderSchema'
import { filterExternalStateLabelList } from '@/pages/transaction/common/statusList';
import { GetOrderProcessingOrderListResponseDetail } from '@/services/OrderV2Api';
const formActions = createFormActions();
const { onFieldInit$ } = FormEffectHooks
registerVirtualBox('MellowCardBox', (_props) => {
const { children, props: outerProps } = _props;
const props = outerProps['x-component-props'] || {};
......@@ -48,6 +51,9 @@ type EnterpriceType = {
memberId: number | string,
roleId: number | string
}
type submitDataType = {}
/** @tofix 临时的,因为后端不返回只能值么临时搞着 */
const MALL_NAME = {
"1": "企业商城",
......@@ -56,6 +62,9 @@ const MALL_NAME = {
"4": "渠道自有商城"
}
/** 来源 加工订单或者是加工商品 */
const ORDER_SOURCE = 1
const Create = () => {
const authInfo = getAuth();
const anchorColumn = useMemo(() => {
......@@ -82,18 +91,21 @@ const Create = () => {
const { visible, toggle } = useModal();
const [enterprice, setEnterprise] = useState<EnterpriceType[]>([])
/** ---- 加工商品 */
/** ---- 加工商品 ---- */
const { visible: processProductVisible, toggle: processProductToggle } = useModal();
const [processProduct, setProcessProduct] = useState([]);
/** ---- 加工商品 ---- */
// const useFields = () =>
// useMemo(() => {
// return {
// string: ReadOnlyInput
// }
// }, [])
/** ---- 编辑商品 ---- */
const { visible: productDrawerVisible, toggle: productDrawerToggle } = useModal();
const [currentProduct, setCurrentProduct] = useState<productInfo | null>(null);
/** ---- 编辑商品end ---- */
/** ---------- 加工企业相关 ----------- */
/** ---- 加工订单 ------- */
const { visible: processOrderVisible, toggle: processOrderToggle } = useModal();
const [orderProductSelectRowKeys, setOrderProductSelectRowKeys] = useState<string[]>([])
const [orderProductselectRowRecord, setOrderProductSelectRowRecord] = useState<{[key: string]: any}[]>([]);
/** ---- 加工订单end ------- */
/**
* 获取加工企业
......@@ -133,9 +145,18 @@ const Create = () => {
}, [])
/** ----------- 加工企业结束 --------- */
const onClickAddProcess = () => {
const source = formActions.getFieldValue('source');
if (source === ORDER_SOURCE) {
processOrderToggle(true)
return;
}
processProductToggle(true)
}
/** -------------- 加工商品相关 --------------- */
const renderAddProduct = () => (
<div onClick={() => processProductToggle(true)} style={{display: 'flex', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#E3E4E5', cursor: 'pointer'}}>
<div onClick={onClickAddProcess} style={{display: 'flex', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#E3E4E5', cursor: 'pointer'}}>
<PlusOutlined /> 添加
</div>
)
......@@ -175,17 +196,20 @@ const Create = () => {
* 2. 渠道企业会员+渠道个人会员,角色类型:服务提供者,数据来源于渠道商品管理,取已上架至商城环境为WEB且商城类型为渠道商城或渠道自有商城的商品。
*/
const handleFetchProductList = useCallback(async (params: any) => {
const { current, pageSize, ...rest } = params;
const { current, pageSize, brandId, ...rest } = params;
const customerCategoryId = params.customerCategoryId && Array.isArray(params.customerCategoryId) && params.customerCategoryId.pop();
const postData = {
/** 商城类型:1-企业商城,2-积分商城,3-渠道商城,4-渠道自有商城,5-渠道积分商城 */
shopType: ENTERPRISE_MALL[authInfo.memberType],
/** 商城环境:1-Web,2-H5,3-小程序,4-App */
environment: 1,
memberId:authInfo.memberId,
customerCategoryId: customerCategoryId,
brandId: brandId,
current: current,
pageSize: pageSize
}
const { data, code } = await PublicApi.getProductCommodityCommonGetCommodityListByBuyer(postData);
const { data, code } = await PublicApi.getProductCommodityCommonGetCommodityListByBuyer(postData as any);
if (code === 1000) {
return data
}
......@@ -214,11 +238,283 @@ const Create = () => {
})
}
})
const handleBeforeProductChecked = useCallback(async (record: GetProductCommodityCommonGetCommodityListByBuyerResponseDetail, selected: boolean, list: GetProductCommodityCommonGetCommodityListByBuyerResponseDetail[]) => {
const postData = list.map((item) => {
return {
/**
* 这里指的是skuid, 而接口getProductCommodityCommonGetCommodityListByBuyer 的主键id 就是skuid, 不是(commodityId)
*/
productId: item.id,
memberId: item.memberId || authInfo.memberId,
memberRoleId: item.memberRoleId || authInfo.memberRoleId,
shopId: ENTERPRISE_MALL[authInfo.memberType],
/** 1.订单交易流程2.售后换货流程3.售后退货流程4.售后维修流程, @todo 5是后端说的,具体不知道代表什么意思? */
type: 5,
}
})
const {code, data, ...rest} = await PublicApi.postOrderGetProcessEnum({list: postData}, {ctlType: 'none'});
if (code !== 1000) {
message.error(rest.message);
return false
}
const hasNoSetProcessEnum = data.some((_item) => _item.processEnum === 0);
if(hasNoSetProcessEnum) {
message.error("当前所选商品没有配置工作流");
return false
}
const differentProcessEnumList = new Set(
data.map((_item) => _item.processEnum)
)
if (differentProcessEnumList.size > 1) {
message.error("当前所选商品配置的工作流不一致");
return false
}
return true
}, [])
/**
* 确认勾选加工商品
*/
const tiggerProcessProductOk = (selectRowKeys: string[] | number[], selectRowRecord: GetProductCommodityCommonGetCommodityListByBuyerResponseDetail[] ) => {
const productList = formActions.getFieldValue('detail.layout1.productList');
const uniqueIdList = new Set(productList.map((_item) => _item.skuid));
/** 获取新增数列 */
const newAddList = selectRowRecord
.filter((_item) => !uniqueIdList.has(_item.id))
.map((_item) => {
return {
skuid: _item.id,
commodityId: _item.commodityId,
mainPic: _item.mainPic,
name: _item.name,
category: _item.customerCategoryName,
brand: _item.brandName,
unitName: _item.unitName,
}
});
const selectRowId = new Set(selectRowRecord.map((_item) => _item.id));
// 过滤减少项
const hasRemoveListRes = []
productList.forEach((_item) => {
if(selectRowId.has(_item.skuid)) {
hasRemoveListRes.push(_item)
}
})
const newDataSource = hasRemoveListRes.concat(newAddList)
formActions.setFieldValue('detail.layout1.productList', newDataSource);
setProcessProduct(newDataSource.map((_item) => ({ ..._item, id: _item.skuid})))
processProductToggle(false);
}
const renderProductListTableRemove = (index: number) => (
<Space>
<a onClick={() => handleEdit(index)}>修改</a>
<a onClick={() => handleRemove(index)}>删除</a>
<a>查看</a>
</Space>
);
const handleRemove = (index: number) => {
const source = formActions.getFieldValue('source');
const isOrderSource = source === ORDER_SOURCE
const productList = isOrderSource ? formActions.getFieldValue('detail.layout1.orderList') : formActions.getFieldValue('detail.layout1.productList');
const target = productList[index];
productList.splice(index, 1);
if (isOrderSource) {
const key = `${target.orderId}_${target.id}`
setOrderProductSelectRowKeys((prev) => prev.filter((_row) => (_row !== key)));
setOrderProductSelectRowRecord((prev) => prev.filter((_item) => `${_item.orderId}_${_item.id}` !== key ))
formActions.setFieldValue('detail.layout1.orderList', productList)
} else {
setProcessProduct((prev) => prev.filter((_item) => _item.skuid !== target.skuid ));
formActions.setFieldValue('detail.layout1.productList', productList)
}
}
const handleEdit = async (index: number) => {
const source = formActions.getFieldValue('source')
const productList = source === ORDER_SOURCE ? formActions.getFieldValue('detail.layout1.orderList') : formActions.getFieldValue('detail.layout1.productList');
// 这里理论不需要判断target 存不存在
let target: productInfo = productList[index];
console.log(target);
/** 获取商品属性, @unknown 不知道为什么后台不一起返回。。。 */
const { data, code } = await PublicApi.getProductCommodityGetCommodityAttributeByUnitPriceAndPicId({
unitPriceAndPicId: target.skuid.toString(),
})
const { skuid, commodityId, category, brand, name, unitName, isHasTaxAndTaxRate, isHasTax, taxRate, processNum, processUnitPrice, enclosure} = target as productInfo;
if (code === 1000) {
const other = source === ORDER_SOURCE ? { orderId: target.orderId, orderNo: target.orderNo, id: target.id } : {}
target = {
...other,
skuid,
commodityId,
category,
brand,
name,
unitName,
isHasTaxAndTaxRate,
isHasTax,
taxRate,
processNum,
processUnitPrice,
enclosure,
/**
* 商品属性
*/
productProps: data.map((_item) => {
return {
name: _item.customerAttribute.name,
value: _item.customerAttributeValueList?.[0].value || ''
}
})
}
}
setCurrentProduct(target);
productDrawerToggle(true);
}
const handleChangeProduct = (values: productSubmitType) => {
console.log(values)
const source = formActions.getFieldValue('source')
const isOrderSource = source === ORDER_SOURCE
const productList = isOrderSource ? formActions.getFieldValue('detail.layout1.orderList') : formActions.getFieldValue('detail.layout1.productList');
// const productList = formActions.getFieldValue('detail.layout1.productList');
const { isHasTax, taxRate, processNum, processUnitPrice, enclosure, productProps } = values;
const newData = productList.map((_item) => {
/** 加工商品的时候用sku, 如果是加工订单商品的话用orderid */
if ((!isOrderSource && _item.skuid === values.skuid) || (isOrderSource && _item.id === values.id)) {
const other = isOrderSource ? { surplusAndProcessNum: _item.purchaseCount - +processNum } : {}
return {
..._item,
...other,
isHasTax,
taxRate,
isHasTaxAndTaxRate: `${isHasTax ? '是' : '否'}/${taxRate}%`,
processUnitPrice,
processNum: processNum,
processTotalPrice: `${priceFormat(+processUnitPrice * +processNum)}`,
enclosure: enclosure?.map((_row) => ({
name: _row.name,
url: _row.url
})) || []
// ...values,
}
}
return _item;
})
formActions.setFieldValue(source === ORDER_SOURCE ? 'detail.layout1.orderList' : 'detail.layout1.productList', newData);
productDrawerToggle(false);
}
/** -------------- 加工商品相关结束 --------------- */
/** ------- 加工订单相关 -------*/
const onSelectChange = async (record: GetOrderProcessingOrderListResponseDetail["productDateilss"][0], selected: boolean, selectedRows) => {
const key = `${record.orderId}_${record.id}`
if (!selected) {
setOrderProductSelectRowKeys((prev) => prev.filter((_row) => (_row !== key)));
setOrderProductSelectRowRecord((prev) => prev.filter((_item) => `${_item.orderId}_${_item.id}` !== key ))
} else {
setOrderProductSelectRowKeys((prev) => prev.concat(key))
setOrderProductSelectRowRecord((prev) => prev.concat(record))
}
};
const orderProductRowSelection = {
// type: 'checkbox',
selectedRowKeys: orderProductSelectRowKeys,
onSelect: onSelectChange,
// onSelectAll: onSelectAll
}
const handleFetchOrderList = useCallback(async (params: any) => {
const { data, code } = await PublicApi.getOrderProcessingOrderList(params as any);
if (code === 1000) {
return data
}
return {
totalCount: 0,
data: []
}
}, [])
/** @tofix 有bug */
const handleBeforeOrderChecked = (record: GetOrderProcessingOrderListResponseDetail, checked: boolean, selectedRows: GetOrderProcessingOrderListResponseDetail[]) => {
let productRow = selectedRows.reduce((prev, current) => {
const { productDateilss, orderNo } = current;
const withOrderNo = productDateilss.map((_row) => ({..._row, orderNo}))
const result = prev.concat(withOrderNo)
return result
}, [])
const orderProductKeys = productRow.map((_item) => `${_item.orderId}_${_item.id}`);
setOrderProductSelectRowKeys(orderProductKeys);
setOrderProductSelectRowRecord(productRow)
return true;
}
const tiggerProcessOrderProductOk = () => {
// const productOrderList = orderProductselectRowRecord.
const orderList = formActions.getFieldValue('detail.layout1.orderList');
console.info(orderProductselectRowRecord, orderList)
const uniqueIdList = new Set(orderList.map((_item) => `${_item.orderId}_${_item.id}`));
/** 获取新增数列 */
const newAddList = orderProductselectRowRecord
.filter((_item) => !uniqueIdList.has(`${_item.orderId}_${_item.id}`))
.map((_item) => {
return {
orderNo: _item.orderNo,
orderId: _item.orderId,
/** 主键id */
id: _item.id,
skuid: _item.productId,
commodityId: _item.commodityId || _item.productId,
mainPic: _item.imgUrl,
name: _item.productName,
category: _item.category,
brand: _item.brand,
unitName: _item.unit,
purchaseCount: _item.purchaseCount,
purchaseCountAndUnit: `${_item.purchaseCount}/${_item.unit}`
}
});
const selectRowId = new Set(orderProductselectRowRecord.map((_item) => `${_item.orderId}__${_item.id}`));
// 过滤减少项
const hasRemoveListRes = []
orderList.forEach((_item) => {
if(selectRowId.has(_item.skuid)) {
hasRemoveListRes.push(_item)
}
})
const newDataSource = hasRemoveListRes.concat(newAddList);
formActions.setFieldValue('detail.layout1.orderList', newDataSource);
// setProcessProduct(newDataSource.map((_item) => ({ ..._item, id: _item.skuid})))
processOrderToggle(false);
}
/** ------- 加工订单相关end------- */
const onSubmit = (value) => {
console.log(value)
}
return (
......@@ -239,6 +535,11 @@ const Create = () => {
<NiceForm
onSubmit={onSubmit}
// fields={useFields() as any}
initialValues={
{
source: 1
}
}
actions={formActions}
schema={creataSchema}
expressionScope={{
......@@ -254,12 +555,14 @@ const Create = () => {
<span style={{marginLeft: 4}}>选择</span>
</div>
),
renderProductListTableRemove: renderProductListTableRemove
// renderAddProduct: renderAddition
}}
components={{
ArrayTable,
FormilyUploadFiles,
renderAddProduct
renderAddProduct,
ReadOnly,
}}
></NiceForm>
</AnchorPage>
......@@ -289,7 +592,7 @@ const Create = () => {
title={"选择加工商品"}
columns={productColumn}
schema={productSchema}
onOk={triggerOk}
onOk={tiggerProcessProductOk}
fetchData={handleFetchProductList}
tableProps={{
rowKey: (record) => `${record.id}`,
......@@ -304,9 +607,55 @@ const Create = () => {
})
}}
mode={"checkbox"}
// value={enterprice}
beforeChecked={handleBeforeProductChecked}
value={processProduct}
/>
<TableModal
modalType={"Drawer"}
width={920}
visible={processOrderVisible}
onClose={() => processOrderToggle(false)}
title={"选择加工订单"}
columns={orderColumns}
schema={orderSchema}
onOk={tiggerProcessOrderProductOk}
fetchData={handleFetchOrderList}
tableProps={{
rowKey: (record) => `${record.id}`,
expandable: {
expandedRowRender: (record) => {
const withOrderNo = record.productDateilss.map((_item) => {
return {
..._item,
orderNo: record.orderNo
}
})
return (
<Table
columns={orderProductColumns}
rowKey={(row) => `${row.orderId}_${row.id}`}
dataSource={withOrderNo}
rowSelection={orderProductRowSelection}
pagination={false}
/>
)
}
}
}}
components={{Cascader}}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'name', FORM_FILTER_PATH);
}}
mode={"checkbox"}
beforeChecked={handleBeforeOrderChecked}
value={processProduct}
/>
<ProductDrawer
visible={productDrawerVisible}
value={currentProduct}
onSubmit={handleChangeProduct}
onClose={() => productDrawerToggle(false)}
/>
</div>
)
}
......
......@@ -246,6 +246,7 @@ const createSchema: ISchema = {
'x-component-props': {
renderAddition: () => null,
renderRemove: () => null,
renderExtraOperations: '{{renderProductListTableRemove}}',
renderMoveDown: () => null,
renderMoveUp: () => null,
operations: {
......@@ -259,16 +260,6 @@ const createSchema: ISchema = {
message: '请选择要加工的商品'
}
],
default: [
{
commodityId: 1,
name: '我的123'
},
{
commodityId: 2,
name: '我的3'
}
],
items: {
type: 'object',
properties: {
......@@ -280,9 +271,13 @@ const createSchema: ISchema = {
width: 65,
},
},
pic: {
mainPic: {
title: '商品图片',
type: "string",
"x-component": 'ReadOnly',
'x-component-props': {
isImage: true,
},
editable: false,
},
name: {
......@@ -300,29 +295,31 @@ const createSchema: ISchema = {
type: 'string',
editable: false,
},
orderNumAndUnit: {
unitName: {
title: '单位',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
},
surplusAndProcessNum: {
title: '剩余/加工数量',
processNum: {
title: '加工数量',
type: 'string',
"x-component": 'ReadOnly',
},
tax: {
isHasTaxAndTaxRate: {
title: '含税/税率',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
},
processUnitPrice: {
title: '加工单价',
type: 'string',
"x-component": 'ReadOnly',
},
processTotalPrice: {
title: '加工费',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
"x-rules": [
{
required: true,
......@@ -330,10 +327,11 @@ const createSchema: ISchema = {
}
],
},
deliveryDate: {
title: "交期",
type: 'string'
}
// deliveryDate: {
// title: "交期",
// type: 'string',
// "x-component": 'ReadOnly',
// }
}
}
},
......@@ -348,6 +346,7 @@ const createSchema: ISchema = {
renderRemove: () => null,
renderMoveDown: () => null,
renderMoveUp: () => null,
renderExtraOperations: '{{renderProductListTableRemove}}',
operations: {
title: '操作'
},
......@@ -359,16 +358,6 @@ const createSchema: ISchema = {
message: '请选择要加工的商品'
}
],
default: [
{
commodityId: 1,
name: '我的'
},
{
commodityId: 2,
name: '我的3'
}
],
items: {
type: 'object',
properties: {
......@@ -388,10 +377,14 @@ const createSchema: ISchema = {
width: 65,
},
},
pic: {
mainPic: {
title: '商品图片',
type: "string",
editable: false,
"x-component": 'ReadOnly',
'x-component-props': {
isImage: true,
},
},
name: {
title: '商品名称',
......@@ -408,29 +401,33 @@ const createSchema: ISchema = {
type: 'string',
editable: false,
},
orderNumAndUnit: {
purchaseCountAndUnit: {
title: '订单数量/单位',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
},
surplusAndProcessNum: {
title: '剩余/加工数量',
type: 'string',
"x-component": 'ReadOnly',
},
tax: {
isHasTaxAndTaxRate: {
title: '含税/税率',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
},
processUnitPrice: {
title: '加工单价',
type: 'string',
"x-component": 'ReadOnly',
},
processTotalPrice: {
title: '加工费',
type: 'string',
editable: false,
"x-component": 'ReadOnly',
"x-rules": [
{
required: true,
......@@ -438,10 +435,6 @@ const createSchema: ISchema = {
}
],
},
deliveryDate: {
title: "交期",
type: 'string'
}
}
}
},
......
......@@ -28,7 +28,8 @@ interface Iprops {
columns: ColumnsType,
footer?: React.ReactNode,
tableProps?: {
rowKey: string | ((record) => any)
rowKey: string | ((record) => any),
expandable?: any,
},
width?: number,
mode: 'checkbox' | 'radio',
......@@ -50,11 +51,35 @@ interface Iprops {
fetchData: (params: any) => any,
onClose: () => void,
onOk: (selectRow: number[] | string[], selectedRows: {[key: string]: any}[]) => void,
/**
* 勾选前操作,
*/
beforeChecked?: ((record: any, selected: boolean, selectedRows: any[]) => boolean) | ((record: any, selected: boolean, selectedRows: any[]) => Promise<any>)
}
const TableModal: React.FC<Iprops> = (props: Iprops) => {
const { title, visible, schema, columns, effects, tableProps, mode, expressionScope, fetchData, onClose, onOk, value, format, customizeRadio, modalType, footer, width, components } = props;
const {
title,
visible,
schema,
columns,
effects,
tableProps,
mode,
expressionScope,
fetchData,
onClose,
onOk,
value,
format,
customizeRadio,
modalType,
footer,
width,
components,
beforeChecked
} = props;
const ref = useRef<any>({});
const isFirstLoad = useRef<boolean>(true)
const [selectRow, setSelectRow] = useState<number[] | string[]>(() => {
......@@ -97,9 +122,16 @@ const TableModal: React.FC<Iprops> = (props: Iprops) => {
isFirstLoad.current = false;
}, [visible])
const onSelectChange = (record, selected: boolean, selectedRows) => {
const onSelectChange = async (record, selected: boolean, selectedRows) => {
const recordRows = customizeRadio || mode === 'radio' ? selectedRows.slice(-1) : selectedRows;
const keys = recordRows.map((_item) => typeof tableProps.rowKey === 'string' ? _item[tableProps.rowKey as string] : tableProps.rowKey(_item));
// if (selected) {
const returnValue =await beforeChecked(record, selected, selectedRows);
if (returnValue === false) {
return;
}
// }
setSelectRowRecord(selectedRows)
setSelectRow(keys)
};
......@@ -190,7 +222,8 @@ TableModal.defaultProps = {
modalType: "Modal",
footer: null,
width: 840,
components: {}
components: {},
beforeChecked: () => true
}
export default TableModal;
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