Commit 549ea305 authored by XieZhiXiong's avatar XieZhiXiong

对接售后维修申请中...

parent 08095c8b
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2020-11-05 10:30:54
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-11-10 10:48:56
* @LastEditTime: 2020-11-13 16:50:01
* @Description: 地址 Form Item
*/
import React, { useEffect, useState } from 'react';
......@@ -22,7 +22,7 @@ interface AddressItem {
};
interface AddressFormItemProps {
value: string;
value: AddressItem;
dataSource: AddressItem[];
// 默认展示的条数
showCount?: number;
......@@ -53,9 +53,9 @@ const AddressFormItem: React.FC<AddressFormItemProps> & { isFieldComponent: bool
setShowMore(!showMore)
};
const handleSelectItem = id => {
const handleSelectItem = record => {
if (onChange) {
onChange(id);
onChange(record);
}
};
......@@ -65,9 +65,9 @@ const AddressFormItem: React.FC<AddressFormItemProps> & { isFieldComponent: bool
{showDataSource.map(item => (
<li
className={classNames(styles['addressList-item'], {
[styles.active]: item.id === value,
[styles.active]: item.id === (value && value.id),
})}
onClick={() => handleSelectItem(item.id)}
onClick={() => handleSelectItem(item)}
key={item.id}
>
<div>
......
......@@ -51,7 +51,7 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
headExtra = null,
}) => {
const [detailInfo, setDetailInfo] = useState<GetAsRepairGoodsGetDetailByConsumerResponse>(null);
const [infoLoading, setInfoloading] = useState(false);
const [infoLoading, setInfoLoading] = useState(false);
const productColumns: EditableColumns[] = [
{
......@@ -112,7 +112,7 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
if (!id) {
return;
}
setInfoloading(true);
setInfoLoading(true);
PublicApi.getAsRepairGoodsGetDetailByConsumer({
repairId: id,
}).then(res => {
......@@ -120,7 +120,7 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
setDetailInfo(res.data);
}
}).finally(() => {
setInfoloading(false);
setInfoLoading(false);
});
};
......
......@@ -175,7 +175,7 @@ const RepairPrFinished: React.FC = () => {
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
rowKey: 'applyId',
}}
columns={columns}
currentRef={ref}
......
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2020-11-04 15:09:09
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-11-12 18:15:53
* @LastEditTime: 2020-11-13 15:54:18
* @Description: 维修商品抽屉组件
*/
import React, { useState, useEffect } from 'react';
......@@ -54,13 +54,28 @@ interface goodItem {
processNum: number;
};
export interface OrderListParams {
orderNo: string;
orderThe: string;
startCreateTime: string;
endCreateTime: string;
type: number;
};
export interface OrderListRes {
data: { [key: string]: any }[];
totalCount: number;
};
interface GoodsDrawerProps {
// 是否可见的
visible: boolean;
// 关闭事件
onClose: () => void;
// 确定时间
// 确定事件
onConfirm: (values: goodItem[]) => void;
// 获取订单列表数据
fetchOrderList: (params: any) => Promise<OrderListRes>;
};
interface GoodsDrawerState {
......@@ -69,12 +84,11 @@ interface GoodsDrawerState {
searchVal: {
orderNo: string,
orderThe: string,
supplyMembersName: string,
startCreateTime: string,
endCreateTime: string,
type: string,
},
dataSource: GetOrderOneBatchOrderListResponse;
dataSource: OrderListRes;
selectedRowKeys: number[];
childSelectedRowKeys: number[];
loading: boolean;
......@@ -89,7 +103,6 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
searchVal: {
orderNo: '',
orderThe: '',
supplyMembersName: '',
startCreateTime: undefined,
endCreateTime: undefined,
type: undefined,
......@@ -176,17 +189,20 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
// 获取订单列表
getOrderList = () => {
const { page, size, searchVal } = this.state;
const { fetchOrderList } = this.props;
if (!fetchOrderList) {
return;
}
this.setState({ loading: true });
PublicApi.getOrderOneBatchOrderList({
fetchOrderList({
current: `${page}`,
pageSize: `${size}`,
...searchVal,
})
.then(res => {
if (res.code === 1000) {
this.setState({ dataSource: res.data });
}
this.setState({ dataSource: res });
})
.finally(() => {
this.setState({ loading: false });
......@@ -212,6 +228,15 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
});
};
handleSearch = values => {
this.setState({
page: 1,
searchVal: values,
}, () => {
this.getOrderList();
});
};
handleClose = () => {
if (this.props.onClose) {
this.props.onClose();
......@@ -240,7 +265,7 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
},
} = this.state;
let childArr: any = [...childSelectedRowKeys];
// 第一步 判断selected true:选中,将 id值 添加到childArr,false:取消选中,将 id值 从childArr中移除
// 第一步,判断selected true:选中,将 id值 添加到childArr,false:取消选中,将 id值 从childArr中移除
if (selected) {
childArr.push(record.id);
} else {
......@@ -374,7 +399,10 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
data.forEach(item => {
item.productDateilss.forEach(product => {
if (childSelectedRowKeys.find(key => key === product.id)) {
fullDate.push(product);
fullDate.push({
...product,
orderNo: item.orderNo, // 手动补全订单单号
});
}
});
});
......@@ -421,7 +449,7 @@ class GoodsDrawer extends React.Component<GoodsDrawerProps, GoodsDrawerState> {
<div className={styles['order-head']}>
<NiceForm
actions={formActions}
onSubmit={values => {}}
onSubmit={this.handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
......
......@@ -52,13 +52,6 @@ export const listSearchSchema: ISchema = {
allowClear: true,
},
},
supplyMembersName: {
type: 'string',
'x-component-props': {
placeholder: '供应会员',
allowClear: true,
},
},
'[startCreateTime, endCreateTime]': {
type: 'string',
default: '',
......
......@@ -2,29 +2,29 @@
* @Author: XieZhiXiong
* @Date: 2020-11-03 18:19:51
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-11-03 18:32:29
* @LastEditTime: 2020-11-13 16:16:47
* @Description:
*/
import { FormEffectHooks, FormPath } from '@formily/antd'
import { useBusinessEffects } from './useBusinessEffects';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { PublicApi } from '@/services/api';
// 获取单据类型
const fetchInvoicesType = (): Promise<any[]> => {
return new Promise((resolve, reject) => {
PublicApi.getWarehouseInvoicesTypeAll().then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
}).catch(() => {
reject();
});
});
};
const { onFormMount$ } = FormEffectHooks;
export const createEffects = (context, actions) => {
const { setFieldState } = actions;
useBusinessEffects(context, actions);
// useAsyncSelect('invoicesTypeId', fetchInvoicesType, ['name', 'id']);
onFormMount$().subscribe(() => {
// 获取收件地址
PublicApi.getLogisticsSelectListReceiverAddress().then(res => {
if (res.code === 1000) {
setFieldState('repairAddress', state => {
state.props['x-component-props'].dataSource = res.data;
});
}
});
});
};
\ No newline at end of file
......@@ -8,7 +8,6 @@
import { Modal } from 'antd';
import { FormEffectHooks, FormPath } from '@formily/antd';
import { useLinkageUtils } from '@/utils/formEffectUtils';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import {
} from '@/constants';
......
import React, { useState, useEffect, useRef } from 'react';
import { Button, Card, Spin, message } from 'antd';
import { Button, Card, Spin, Badge, message } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import { Radio, ArrayTable } from '@formily/antd-components';
import { history, Prompt } from 'umi';
import moment from 'moment';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { SaveOutlined, PlusOutlined } from '@ant-design/icons';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { PublicApi } from '@/services/api';
import { normalizeFiledata, FileData, isJSONStr } from '@/utils';
import ReutrnEle from '@/components/ReturnEle';
import NiceForm from '@/components/NiceForm';
import GoodsDrawer from '../GoodsDrawer';
import StatusTag from '@/components/StatusTag';
import GoodsDrawer, { OrderListRes } from '../GoodsDrawer';
import AddressFormItem from '../../../../components/AddressFormItem';
import { addBillSchema } from './schema';
import { createEffects } from './effects';
import {
REPAIR_OUTER_STATUS_TAG_MAP,
REPAIR_INNER_STATUS_BADGE_MAP,
} from '../../../../constants';
const addSchemaAction = createFormActions();
const {
onFormInputChange$,
} = FormEffectHooks;
interface DetailInfo {
applyTime: string;
faultFileList?: FileData[];
repairAddress?: { [key: string]: any }[];
supplierMember?: {},
}
interface BillsFormProps {
id?: string;
// 是否是编辑的
......@@ -29,19 +43,93 @@ const RepairForm: React.FC<BillsFormProps> = ({
id,
isEdit = false,
}) => {
const [detailInfo, setDetailInfo] = useState<DetailInfo>({
applyTime: moment().format('YYYY-MM-DD HH:mm:ss'),
});
const [visible, setVisible] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const [infoLoading, setInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [visibleDrawer, setVisibleDrawer] = useState(false);
useEffect(() => {
const goodsDrawerRef = useRef(null);
// 获取维修申请详情
const getDetailInfo = () => {
if (!id) {
return;
}
setInfoLoading(true);
PublicApi.getAsRepairGoodsGetDetailByConsumer({
repairId: id,
}).then(res => {
if (res.code === 1000) {
const {
repairAddress,
faultFileList,
supplierName,
...rest
} = res.data;
addSchemaAction.setFieldState(
'*(supplierMember)',
state => {
state.props['x-component-props'].disabled = true;
}
);
setDetailInfo({
faultFileList: faultFileList.map(item => normalizeFiledata(item.filePath)),
repairAddress: isJSONStr(repairAddress) || null,
supplierMember:
supplierName ?
[
{
name: supplierName,
},
] :
[]
,
...rest,
});
}
}).finally(() => {
setInfoLoading(false);
});
};
// 根据供应会员获取订单列表
const getOrderList = (params): Promise<OrderListRes> => {
const supplierMemberValue = addSchemaAction.getFieldValue('supplierMember');
return new Promise((resolve, reject) => {
PublicApi.getOrderOneBatchOrderList({
...params,
supplyMembersId: supplierMemberValue[0].memberId,
supplyMembersRoleId: supplierMemberValue[0].roleId,
}).then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
}).catch(() => {
reject();
});
});
};
useEffect(() => {
getDetailInfo();
}, []);
// 弹出单据明细
const handleAdd = () => {
// do something
const handleAddGoods = () => {
const supplierMemberValue = addSchemaAction.getFieldValue('supplierMember');
if (!supplierMemberValue || !supplierMemberValue.length) {
message.error('请先选择供应会员');
return;
}
setVisibleDrawer(true);
};
const TableAddButton = isEdit || !id ? (
......@@ -49,22 +137,68 @@ const RepairForm: React.FC<BillsFormProps> = ({
style={{ marginBottom: 16 }}
block
icon={<PlusOutlined />}
onClick={() => setVisibleDrawer(true)}
onClick={handleAddGoods}
type="dashed"
>
选择维修商品
</Button>
) : null;
const handleSubmit = value => {
const handleSubmit = values => {
const {
} = value;
console.log('value', value)
supplierMember,
faultFileList,
repairGoodsList,
repairAddress,
...rest
} = values;
console.log('values', values)
return;
setSubmitLoading(true);
const payload = {
repairId: id || 0, // 有 id 表示编辑,0表示新增
supplierMemberId: supplierMember[0].memberId,
supplierRoleId: supplierMember[0].roleId,
supplierName: supplierMember[0].name,
repairAddress: repairAddress ? JSON.stringify(repairAddress) : '',
faultFileList: faultFileList.filter(item => item.status === 'done').map(item => ({
fileName: item.name,
filePath: item.data,
})),
repairGoodsList: repairGoodsList.map(({
id,
repairCount,
brand,
unit,
...rest
}) => ({
repairCount: +repairCount,
brand: brand || '',
unit: unit || '',
...rest,
})),
...rest,
};
PublicApi.postAsRepairGoodsSave(payload)
.then(res => {
if (res.code === 1000) {
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
}
})
.finally(() => {
setSubmitLoading(false);
});
};
const handleRemoveItem = (index: number) => {
const { childSelectedRowKeys } = goodsDrawerRef.current.state;
goodsDrawerRef.current.handleSetChildSelectedRowKeys([]);
// do something
// const newSelectRow = [...productRowCtl.selectRow];
// const newSelectedRowKeys = [...productRowCtl.selectedRowKeys];
......@@ -96,9 +230,39 @@ const RepairForm: React.FC<BillsFormProps> = ({
};
const handleGoodsConfirm = values => {
console.log('values', values);
const preValues = addSchemaAction.getFieldValue('repairGoodsList');
const value = [];
values.forEach(item => {
const existing = preValues.find(val => val.id === item.id);
const atom =
existing ?
existing :
{
id: item.id,
orderId: item.orderId,
orderNo: item.orderNo,
productId: item.productId,
productName: item.productName,
category: item.category,
brand: item.unitName,
unit: item.costPrice,
repairCount: '',
repairReason: '',
};
value.push(atom);
});
addSchemaAction.setFieldValue('repairGoodsList', value);
};
const OuterStatus = (
<StatusTag type={REPAIR_OUTER_STATUS_TAG_MAP[detailInfo?.outerStatus]} title={detailInfo?.outerStatusName} />
);
const InnerStatus = (
<Badge color={REPAIR_INNER_STATUS_BADGE_MAP[detailInfo?.innerStatus]} text={detailInfo?.innerStatusName} />
);
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
......@@ -132,9 +296,11 @@ const RepairForm: React.FC<BillsFormProps> = ({
>
<Card>
<NiceForm
initialValues={{}}
initialValues={detailInfo}
expressionScope={{
TableAddButton,
OuterStatus,
InnerStatus,
renderListTableRemove,
beforeUpload,
}}
......@@ -159,8 +325,10 @@ const RepairForm: React.FC<BillsFormProps> = ({
<GoodsDrawer
visible={visibleDrawer}
fetchOrderList={getOrderList}
onClose={() => setVisibleDrawer(false)}
onConfirm={handleGoodsConfirm}
ref={goodsDrawerRef}
/>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
......
......@@ -37,10 +37,9 @@ const supplierColumns = [
},
];
// 获取供应会员
const getSupplier = async (params) => {
const res = await PublicApi.getMemberManageLowerMerchantProviderPage({
const res = await PublicApi.getMemberManageUpperProviderPage({
...params,
})
if (res.code === 1000) {
......@@ -100,7 +99,12 @@ export const addBillSchema: ISchema = {
applyAbstract: {
type: 'string',
title: '申请单摘要',
required: true,
'x-rules': [
{
required: true,
message: '请填写申请单摘要',
},
],
},
// 这是用 Mega-Layout 设置独立作用域,不然会被 Form 的布局影响到弹窗的布局
MEGA_LAYOUT1_1: {
......@@ -157,7 +161,7 @@ export const addBillSchema: ISchema = {
title: '申请单号',
'x-component': 'Text',
},
createdTime: {
applyTime: {
type: 'string',
title: '单据时间',
'x-component': 'Text',
......@@ -165,12 +169,18 @@ export const addBillSchema: ISchema = {
outerStatus: {
type: 'string',
title: '外部状态',
'x-component': 'Text',
'x-component': 'Children',
'x-component-props': {
children: '{{OuterStatus}}'
},
},
innerStatus: {
type: 'string',
title: '内部状态',
'x-component': 'Text',
'x-component': 'Children',
'x-component-props': {
children: '{{InnerStatus}}'
},
},
},
},
......@@ -198,29 +208,39 @@ export const addBillSchema: ISchema = {
children: '{{TableAddButton}}'
},
},
invoicesDetailsRequests: {
repairGoodsList: {
type: 'array',
'x-component': 'ArrayTable',
'x-component-props': {
renderAddition: () => null,
renderRemove: '{{renderListTableRemove}}',
operationsWidth: 100,
operations: {
align: 'center',
},
},
'x-rules': [
{
required: true,
message: '请选择维修商品',
},
],
items: {
type: 'object',
properties: {
itemNo: {
orderNo: {
type: 'string',
title: '号',
title: '订单号',
'x-component': 'Text',
},
itemNmae: {
productId: {
type: 'string',
title: '货品名称',
title: '商品ID',
'x-component': 'Text',
},
specifications: {
productName: {
type: 'string',
title: '规格型号',
title: '商品名称',
'x-component': 'Text',
},
category: {
......@@ -238,64 +258,55 @@ export const addBillSchema: ISchema = {
title: '单位',
'x-component': 'Text',
},
costPrice: {
type: 'string',
title: '成本价',
'x-component': 'Text',
},
product: {
repairCount: {
type: 'string',
title: '商品名称',
enum: [],
title: '维修数量',
'x-component-props': {
allowClear: true,
style: {
width: 100,
maxWidth: 150,
},
},
'x-rules': [
{
required: true,
message: '请选择商品',
message: '请填写维修数量',
},
{
pattern: PATTERN_MAPS.quantity,
message: '请填写大于等于 0 的整数维修数量',
},
],
},
// 不用于展示,只收集值
productName: {
repairReason: {
type: 'string',
display: false,
},
productId: {
type: 'string',
title: '商品ID',
'x-component': 'Text',
},
price: {
type: 'string',
title: '单价',
'x-component': 'Text',
},
productCount: {
type: 'string',
title: '单据数量',
title: '维修原因',
'x-component-props': {
allowClear: true,
style: {
maxWidth: 150,
},
},
'x-rules': [
{
required: true,
message: '请输入单据数量',
message: '请填写维修原因',
},
{
pattern: PATTERN_MAPS.quantity,
message: '请输入正确的数量',
},
limitByte: true, // 自定义校验规则
maxByte: 60,
}
],
},
amount: {
// 不用于展示,只用于收集值
id: {
type: 'string',
title: '金额',
'x-component': 'Text',
display: false,
},
// 不用于展示,只用于收集值
orderId: {
type: 'string',
display: false,
},
},
}
......@@ -363,33 +374,14 @@ export const addBillSchema: ISchema = {
type: 'string',
'x-component': 'AddressFormItem',
'x-component-props': {
dataSource: [
{
id: 1,
receiverName: '收件人1',
phone: '18128131762',
fullAddress: '不告诉你1',
},
{
id: 2,
receiverName: '收件人2',
phone: '18128131762',
fullAddress: '不告诉你2',
},
{
id: 3,
receiverName: '收件人2',
phone: '18128131762',
fullAddress: '不告诉你2',
},
{
id: 4,
receiverName: '收件人2',
phone: '18128131762',
fullAddress: '不告诉你2',
},
],
dataSource: [],
},
'x-rules': [
{
required: true,
message: '请选择维修地址',
},
],
},
},
},
......
......@@ -112,7 +112,7 @@ const RepairPrSubmit: React.FC = () => {
</Popconfirm>
<Button
type="link"
onClick={() => history.push(`/memberCenter/afterService/repairApplication/repairPrSubmit/edit?id=${record.id}`)}
onClick={() => history.push(`/memberCenter/afterService/repairApplication/repairPrSubmit/edit?id=${record.applyId}`)}
>
编辑
</Button>
......@@ -210,7 +210,7 @@ const RepairPrSubmit: React.FC = () => {
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
rowKey: 'applyId',
}}
columns={columns}
currentRef={ref}
......
......@@ -140,7 +140,7 @@ const RepairQuery: React.FC = () => {
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
rowKey: 'applyId',
}}
columns={columns}
currentRef={ref}
......
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