Commit 74b855c0 authored by Bill's avatar Bill

feat: 对接物料一级审核列表等,详情,货源清单

parent dc774d74
......@@ -59,7 +59,14 @@ registerVirtualBox('flex-layout', (_props) => {
return (
<RowLayout style={rowStyle}>
{
children.map((v, i) => <Col style={colStyle} key={i}>{v}</Col>)
children.map((v, i) => {
const visible = v?.props.schema?.visible ?? true
console.log(v.props)
if (!visible) {
return null;
}
return <Col style={colStyle} key={i}>{v}</Col>
})
}
</RowLayout>
)
......
/**
* 物料内部状态枚举
*/
/** 已冻结 */
export const FROZEN = 0;
/** 待新增物料 */
export const PENDING_ADD_MATERIAL = 1;
/** 待审核物料(一级) */
export const PENDING_EXAM_I = 2;
/** 一级审核不通过 */
export const EXAM_I_FAIL = 3;
/** 待审核物料(二级) */
export const PENDING_EXAM_II = 4;
/** 待审核物料(二级)不通过 */
export const EXAM_II_FAIL = 5;
/**
* 6: {status: 51, name: "待提交审核"}
7: {status: 52, name: "待审核物料(一级)"}
8: {status: 53, name: "一级审核不通过"}
9: {status: 54, name: "待审核物料(二级)"}
10: {status: 55, name: "二级审核不通过"}
11: {status: 99, name: "已确认"}
*/
/** 待提交审核 */
export const PENDING_SUBMIT_EXAM = 51;
/** 待审核变更一级 */
export const PENDING_EXAM_CHANGE_I = 52
/** 待审核变更一级 */
export const PENDING_EXAM_CHANGE_I_FAIL = 53;
/** 待提交变更二级 */
export const PENDING_EXAM_CHANGE_II = 54;
/** 待审核变更二级不通过 */
export const PENDING_EXAM_CHANGE_II_FAIL = 55
/** 已确认 */
export const HAS_CONFIRM = 99
\ No newline at end of file
......@@ -10,8 +10,8 @@ export function getColumn(params: Params) {
{
title: '物料编号',
dataIndex: 'code',
render: () => {
return <Link to='/'></Link>
render: (text, record) => {
return <Link to={`${params.detailUrl}?id=${record.id}`}>{text}</Link>
}
},
{
......@@ -20,7 +20,7 @@ export function getColumn(params: Params) {
},
{
title: '物料组',
dataIndex: 'group'
dataIndex: 'materialGroup'
},
{
title: '规格型号',
......@@ -28,23 +28,33 @@ export function getColumn(params: Params) {
},
{
title: '品类',
dataIndex: 'category'
dataIndex: 'category',
render: (text, record) => {
return (
<div>{record.customerCategory?.name}</div>
)
}
},
{
title: '品牌',
dataIndex: 'brand'
dataIndex: 'brand',
render: (text, record) => {
return (
<div>{record.brand?.name}</div>
)
}
},
{
title: '单位',
dataIndex: 'unit'
dataIndex: 'unitName'
},
{
title: '目录价',
dataIndex: 'price'
dataIndex: 'costPrice'
},
{
title: '内部状态',
dataindex: 'status',
dataIndex: 'interiorStateName',
}
]
return columns.concat(params?.extraColumn || []);
......
......@@ -110,102 +110,3 @@ export const getSchema = (options: Options) => {
};
return schema;
}
export const querySchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
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": 'controllerBtns'
},
code: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '物料编号',
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
colStyle: {
marginLeft: 20,
},
},
properties: {
name: {
type: 'string',
'x-component-props': {
placeholder: '物料名称',
allowClear: true,
},
},
materialGroupId: {
type: 'string',
'x-component': 'Cascader',
'x-component-props': {
placeholder: '物料组',
allowClear: true,
fieldNames: { label: 'title', value: 'id', children: 'children' },
style: { width: '150px' },
showSearch: true
},
},
brandId: {
type: 'string',
enum: [],
'x-component-props': {
placeholder: '品牌',
allowClear: true,
showSearch: true,
style: { width: '150px' },
},
},
categoryId: {
type: 'string',
'x-component': 'Cascader',
'x-component-props': {
placeholder: '品类',
allowClear: true,
style: { width: '150px' },
showSearch: true,
fieldNames: { label: 'title', value: 'id', children: 'children' },
},
},
status: {
type: 'string',
'x-component-props': {
placeholder: '内部状态',
allowClear: true,
enum: [],
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({id: 'handling.chaxun'}),
},
},
},
},
},
},
},
};
\ No newline at end of file
import StatusTag from '@/components/StatusTag';
import { GetProductGoodsGetGoodsProcessDetailResponse } from '@/services/ProductV2Api';
import { findLastIndexFlowState } from '@/utils';
import { useMemo, useState } from 'react';
import FileItem from '../components/fileItem';
type Options<T = any> = {
type Options<T> = {
initialValue: T
}
......@@ -11,7 +12,7 @@ type Options<T = any> = {
* 该hook 作为获取详情页进本信息
* @param options
*/
function useGetDetailCommon<T = any>(options: Options<T>) {
function useGetDetailCommon<T extends GetProductGoodsGetGoodsProcessDetailResponse>(options: Options<T>) {
const { initialValue } = options;
const anchorHeader = useMemo(() => [
......@@ -24,16 +25,20 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
name: '基本信息'
},
{
key: 'type',
name: '物料分类'
},
{
key: 'type',
key: 'properties',
name: '物料规格'
},
{
key: 'images',
name: '物料图片'
},
{
key: 'files',
name: '物料图片'
},
{
key: 'log',
name: '物料图片'
}
], []);
......@@ -41,19 +46,19 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
return [
{
title: '物料编号',
value: 'ME31'
value: initialValue?.code
},
{
title: '单位',
value: 'KG'
value: initialValue?.unitName
},
{
title: '物料名称',
value: '生产物料'
value: initialValue?.name
},
{
title: '目录价',
value: '¥15.50'
value: initialValue?.costPrice
},
{
title: '规格型号',
......@@ -61,28 +66,30 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
},
{
title: '品牌',
value: 'pelle'
value: initialValue?.brand?.name
},
{
title: '所属物料组',
value: '生产物料'
value: initialValue?.materialGroup?.name
},
{
title: '备注',
value: '123123'
value: '备注唔'
},
{
title: '品类',
value: (
<div>
成品皮 -> 牛皮 -> 头层牛皮
{
initialValue?.customerCategory?.name
}
</div>
)
},
{
title: '物料状态',
value: (
<StatusTag title="已确认" type="primary" />
<StatusTag title={initialValue?.interiorStateName} type="primary" />
)
}
]
......@@ -90,6 +97,23 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
}, [initialValue])
/** 动态物料属性 */
const properties = useMemo(() => {
if (!initialValue?.materialAttributeList) {
return [];
}
const result = initialValue?.materialAttributeList.map((_item) => {
return {
title: _item.customerAttribute.name,
value: _item.customerAttributeValueList.map((_row) => {
return _row.value
}).join('')
}
})
return result
}, [initialValue?.materialAttributeList])
/**
* 获取当前工作流
*/
......@@ -99,16 +123,16 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
stepName: string,
roleName: string,
status: 'finish' | 'wait',
}[] = initialValue && initialValue.verifySteps ?
initialValue.verifySteps.map(item => ({
step: item.step,
stepName: item.stepName,
}[] = initialValue?.simpleProcessDefVO ?
initialValue?.simpleProcessDefVO?.tasks?.map(item => ({
step: item.taskStep,
stepName: item.taskName,
roleName: item.roleName,
status: initialValue?.currentStep > item.step ? 'finish' : 'wait',
status: initialValue?.simpleProcessDefVO?.currentStep > item.taskStep ? 'finish' : 'wait',
})) :
[]
const innerVerifyCurrent = findLastIndexFlowState(initialValue?.verifySteps)
console.log(innerVerifySteps)
const innerVerifyCurrent = findLastIndexFlowState(initialValue?.simpleProcessDefVO.tasks)
const outerVerifyCurrent = 0
const outerVerifySteps = null
return {
......@@ -137,7 +161,7 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
dataIndex: 'desc'
}
]
}, [])
}, [initialValue])
/**
* 内部单据流转记录
......@@ -147,23 +171,28 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
return [
{
title: '流转记录',
dataIndex: 'id'
dataIndex: 'id',
render: (text, record, index) => {
return (
<div>{index}</div>
)
}
},
{
title: '操作人',
dataIndex: 'operator'
dataIndex: 'roleName'
},
{
title: '部门',
dataIndex: 'apartment'
dataIndex: 'department'
},
{
title: '职位',
dataIndex: 'pos'
dataIndex: 'position'
},
{
title: '状态',
dataIndex: 'status'
dataIndex: 'state'
},
{
title: '操作',
......@@ -171,16 +200,16 @@ function useGetDetailCommon<T = any>(options: Options<T>) {
},
{
title: '操作时间',
dataIndex: 'time'
dataIndex: 'createTime'
},
{
title: '备注',
dataIndex: 'remark'
dataIndex: 'auditOpinion'
}
]
}, [])
return { anchorHeader: anchorHeader, auditProcess, basicInfoList, tableColumn, recordColumn }
return { anchorHeader: anchorHeader, auditProcess, basicInfoList, tableColumn, recordColumn, properties }
}
export default useGetDetailCommon
\ No newline at end of file
import { useEffect, useState } from "react";
type ResponseType<T> = {
data: T,
code: number,
message: string
}
type Options<Q, R> = {
id: string;
api: (params: { id: string }) => Promise<ResponseType<Q>>
logApi: (params: { goodsId: string }) => Promise<ResponseType<R>>
}
function useGetInitialValueDetail<T, R extends any[]>(options: Options<T, R>) {
const [initialValue, setInitialValue] = useState<T>(null);
const [record, setRecord] = useState<R>([] as R);
useEffect(() => {
async function getInitialValue() {
const { data, code } = await options.api({id: options.id})
if (code === 1000) {
setInitialValue(data)
}
}
getInitialValue();
}, [])
useEffect(() => {
if (!options.logApi) {
return;
}
async function getLogger() {
const { data, code } = await options.logApi({goodsId: options.id})
if (code === 1000) {
setRecord(data)
}
}
getLogger();
}, [])
return { initialValue, record };
}
export default useGetInitialValueDetail
\ No newline at end of file
import React from 'react';
import { TreeSelect } from 'antd';
const { TreeNode } = TreeSelect;
interface Iprops {
props: {
enum: any[]
['x-component-props']: {
currentId: number
}
},
value: string,
mutators: {
change: (params: any) => void
remove: (index: number) => void
},
}
const FormilyTreeSelect: React.FC<Iprops> & { isFieldComponent: boolean } = (props: Iprops) => {
const { mutators, value } = props;
const options = props.props.enum || [];
const xComponentProps = props.props['x-component-props'];
const onChange = (value) => {
mutators.change(value);
}
const subTreeNode = (subTree) => {
return (
subTree.map((_item) => {
if (_item.id === xComponentProps.currentId) {
return subTreeNode(_item.children)
}
return (
<TreeNode value={_item.id} title={_item.title} key={_item.id}>
{
subTreeNode(_item.children)
}
</TreeNode>
)
})
)
}
return (
<TreeSelect
showSearch
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
placeholder="Please select"
allowClear
treeDefaultExpandAll
onChange={onChange}
value={value}
>
{
subTreeNode(options)
}
</TreeSelect>
)
}
FormilyTreeSelect.isFieldComponent = true
export default FormilyTreeSelect;
\ No newline at end of file
/**
* 详情页审核
* 用于详情页,一级审核, 二级审核,
* 这里本来想写根据schema,渲染table的。。。但感觉好像有问题
*/
import React, { useEffect, useMemo } from 'react';
import { createAsyncFormActions, createFormActions, ISchema, FormEffectHooks } from '@formily/antd';
import { Modal, Cascader } from 'antd';
import NiceForm from '@/components/NiceForm';
import { getIntl } from 'umi';
const formActions = createFormActions();
const intl = getIntl();
export type AddressOptionType = {
label: string,
value: string | number,
}
interface Iprops {
/**
* 显示/隐藏
*/
visible: boolean,
/**
* 模态框标题
*/
title: string,
/**
* value, 表单值
*/
value?: { [key: string]: any },
/**
* 是否显示label
*/
showLabel?: boolean
/**
* align: label 显示方式
*/
align?: "left" | "top",
/**
* 提交
*/
onSubmit: (value: {[key: string]: any}) => void,
onCancel: () => void
}
export type SubmitDataTypes = {
/**
* 当审核不通过时,才有审核不通过原因填写
*/
reason?: string,
}
const FrozonMadal: React.FC<Iprops> = (props: Iprops) => {
const { title, visible, onSubmit, onCancel, value, showLabel, align } = props;
const schema: ISchema = useMemo(() => ({
type: 'object',
properties: {
layout: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
// labelCol: showLabel ? 5 : 0,
labelAlign: align,
full: true,
// labelAlign: 'left'
},
properties: {
reason: {
title: '冻结',
type: 'textarea',
'x-rules': [
{
required: true,
message: intl.formatMessage({id: 'components.qingtianxieshenhebutongguo'}),
},
],
},
}
}
}
}), [showLabel, align])
const handleOk = () => {
formActions.submit()
}
const handleFormSubmit = (values: SubmitDataTypes) => {
const {...res } = values;
const postData = values
onSubmit?.(postData)
}
const handleCancel = () => {
onCancel?.();
}
// useEffect(() => {
// if (!visible) {
// return ;
// }
// if (!value) {
// return ;
// }
// if (value.status === 0) {
// formActions.setFieldState('status', state => {
// state.editable = false;
// })
// }
// }, [visible, value])
return (
<Modal
title={title}
visible={visible}
onOk={handleOk}
onCancel={handleCancel}
>
<NiceForm
value={value}
actions={formActions}
schema={schema}
onSubmit={handleFormSubmit}
/>
</Modal>
)
}
FrozonMadal.defaultProps = {
// schema: defaultSchema,
value: {},
showLabel: true,
align: "top",
}
export default FrozonMadal
\ No newline at end of file
import React from 'react';
const ImageList = () => {
interface Iprops {
imageUrls: string[];
}
const ImageList: React.FC<Iprops> = (props: Iprops) => {
const { imageUrls } = props;
return (
<div
style={{
......@@ -11,7 +16,7 @@ const ImageList = () => {
}}
>
{
[1,2,3,4,5,6,7,8,9].map((key) => {
imageUrls?.map((key) => {
return (
<div
key={key}
......@@ -27,7 +32,7 @@ const ImageList = () => {
border: '1px solid #F4F5F7',
borderRadius: '4px',
}}
src="https://img0.baidu.com/it/u=1200036887,40760142&fm=253&fmt=auto&app=138&f=JPEG?w=480&h=600"
src={key}
/>
</div>
)
......
......@@ -55,17 +55,7 @@ interface InitTreeData {
}
}
/**
* dragNode
*/
interface DragStartAction {
type: 'dragStart',
payload: {
dragNode: any
}
}
type Action = SelectAction | SortAction | InitTreeData | DragStartAction;
type Action = SelectAction | SortAction | InitTreeData ;
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
......@@ -88,12 +78,6 @@ const reducer: Reducer<State, Action> = (state, action) => {
treeData: action.payload.treeData
}
}
case 'dragStart': {
return {
...state,
dragNode: action.payload.dragNode
}
}
default:
throw new Error()
}
......@@ -232,23 +216,6 @@ const MaterialTree: React.FC<Iprops> = (props: Iprops) => {
})
};
const onDragStart = (info: onDropStartParameters[0]) => {
dispatch({
type: 'dragStart',
payload: {
dragNode: info.node
}
})
}
const onDragEnd = (info: onDropStartParameters[0]) => {
console.log("onDropEnd", info);
props.onDragEnd?.({
startNode: state.dragNode,
endNode: info.node
})
}
const handleSelect = (selectedKeys: onSelectParameters[0], event: onSelectParameters[1]) => {
onSelect?.(selectedKeys, event)
dispatch({
......
......@@ -8,7 +8,7 @@ import ProcessRadio from './components/processRadio';
import ApplicableMaterial from './components/applicableMaterials';
import SelectMaterial from './components/selectMaterial';
import { Button } from 'antd';
import { getProductMaterialGroupTree, getProductMaterialProcessBaseList, getProductMaterialProcessGet, postProductMaterialProcessSave, postProductMaterialProcessUpdate } from '@/services/ProductV2Api';
import { getProductMaterialGroupTree, getProductMaterialProcessBaseList, getProductMaterialProcessGet, getProductMaterialProcessPageRelMaterial, postProductMaterialProcessSave, postProductMaterialProcessUpdate } from '@/services/ProductV2Api';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import FormilyTransfer from './components/formilyTransfer';
import { usePageStatus } from '@/hooks/usePageStatus';
......@@ -36,7 +36,6 @@ type SubmitDataType = {
/**
* 新增物料审核流程规则
*/
const EMPTY = [];
const anchorHeader = [
{
......@@ -45,7 +44,7 @@ const anchorHeader = [
},
{
name: '物料流程',
key: 'process',
key: 'type',
},
{
name: '适用物料组/物料',
......@@ -71,9 +70,17 @@ const Add = () => {
const { data, code } = await getProductMaterialProcessGet({ processId: id });
console.log(data);
if (code === 1000) {
/** 选择部分物料 */
let materials = [];
if (data.suitableMaterialType === 3) {
const listData = await getProductMaterialProcessPageRelMaterial({ processId: id })
materials = [...listData.data];
}
setInitialValue({
...data,
materialGroups: ['15']
materials: materials,
// materialGroups: ['15']
});
}
}
......
......@@ -65,7 +65,7 @@ export const addSchema: ISchema = {
type: 'object',
"x-component": 'MellowCard',
"x-component-props": {
id: 'type1',
id: 'apply',
title: '适用物料组/物料'
},
properties: {
......
......@@ -6,8 +6,11 @@ import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { schema } from './schema';
import { FormState } from '@/hooks/useTreeData';
import { FormButtonGroup } from '@formily/antd';
import { createAsyncFormActions, FormButtonGroup, FormPath } from '@formily/antd';
import { getProductMaterialGroupDetail, getProductMaterialGroupTree, GetProductMaterialGroupTreeResponse, postProductMaterialGroupDelete, postProductMaterialGroupSaveOrUpdate } from '@/services/ProductV2Api';
import FormilyTreeSelect from '../components/formilyTreeSelect';
const formActions = createAsyncFormActions();
interface Iprops {}
......@@ -74,12 +77,23 @@ const MaterialGroup = () => {
setFormValue(null)
setInfo(null)
return;
}
setInfo({
status: 'edit',
parentId: null,
id: event.node.key
})
formActions.setFieldState('parentId', (state) => {
FormPath.setIn(state, 'props.enum', [{
parentId: 0,
title: '顶级',
key: 0,
id: 0,
children: treeData
}])
FormPath.setIn(state, 'props.x-component-props', { currentId: event.node.key })
})
const { data, code } = await getProductMaterialGroupDetail({ id: `${event.node.key}` })
if (code === 1000) {
setFormValue(data)
......@@ -114,6 +128,9 @@ const MaterialGroup = () => {
description: '',
name: ''
})
formActions.setFieldState('parentId', (state) => {
FormPath.setIn(state, 'visible', false)
})
}
const handleDelete = async () => {
......@@ -128,14 +145,9 @@ const MaterialGroup = () => {
status: 'create',
parentId: 0,
})
}
const onSortEnd = (sortedTreeData) => {
console.log(sortedTreeData);
}
const onDragEnd = ({ startNode, endNode }) => {
console.info(startNode, endNode);
formActions.setFieldState('parentId', (state) => {
FormPath.setIn(state, 'visible', false)
})
}
return (
......@@ -158,8 +170,6 @@ const MaterialGroup = () => {
treeData={treeData}
onSelect={onSelect}
onAdd={handleAdd}
onSortEnd={onSortEnd}
onDragEnd={onDragEnd}
/>
</Card>
</div>
......@@ -171,8 +181,10 @@ const MaterialGroup = () => {
) || (
<NiceForm
value={formValue}
components={{FormilyTreeSelect}}
schema={schema}
onSubmit={onSubmit}
actions={formActions}
>
<FormButtonGroup>
<Button htmlType='submit' type="primary" >
......
......@@ -44,6 +44,16 @@ export const schema: ISchema = {
description: {
title: '物料组描述',
type: 'textarea',
},
parentId: {
title: '父级',
type: 'FormilyTreeSelect',
'x-rules': [
{
required: true,
message: '请选择父级'
}
]
}
}
}
......
......@@ -93,7 +93,7 @@ const MaterialAdd = () => {
<UploadFiles onChange={handleChange} showFiles={false}>
<div className={styles.addition}>
<PlusOutlined />
<span className={styles.text}>新增附件信息</span>
<span className={styles.text}>添加供应商信息</span>
</div>
</UploadFiles>
)
......@@ -127,9 +127,9 @@ const MaterialAdd = () => {
const commodityAttributeList = dynamicProps.map((_item) => {
const [ ,customerAttributeId] = _item.match(/customerAttribute-(\d+)/);
const toArrayData = Array.isArray(rest[_item]) ? rest[_item] : [rest[_item]]
console.log(toArrayData)
const customerAttributeValueList = toArrayData.map((_row) => {
const splitData = _row.split("-");
const splitData = _row?.split("-");
return {
id: splitData[0],
value: splitData[1]
......@@ -244,7 +244,7 @@ const MaterialAdd = () => {
title: name,
type: 'string',
...withEnum,
// ...withRequire
...withRequire
}
})
setSchema(
......
......@@ -6,11 +6,11 @@ import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Dropdown, Menu, message, Space } from 'antd';
import { Button, Card, Dropdown, Menu, message, Modal, Space } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions, Schema } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { getProductGoodsGetGoodsList, GetProductGoodsGetMaterialListRequest, postProductGoodsDeleteBatchGoods } from '@/services/ProductV2Api';
import { getProductGoodsGetGoodsList, GetProductGoodsGetMaterialListRequest, postProductGoodsDeleteBatchGoods, postProductGoodsSubmit } from '@/services/ProductV2Api';
import { SearchParams } from '../materialQuery';
import { EMPTY, fetchBrand, fetchCategoryData, fetchTreeData, useAsyncCascader } from '../common/useGetTableSearchData';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
......@@ -31,27 +31,39 @@ const MaterialQuery = () => {
customKey: 'id',
});
const handleDelete = async (_row) => {
const { data, code } = await postProductGoodsDeleteBatchGoods({ idList: [_row.id] });
if (code === 1000) {
formActions.submit();
}
}
const handleSubmit = async (_row) => {
const { data, code } = await postProductGoodsSubmit({ id: _row.id });
if (code === 1000) {
formActions.submit();
} else if (code === 43149) {
Modal.warning({
title: '提交提醒',
content: `当前还未创建审核工作流, 请在物料审核流程规则配置设置`,
onOk() {
console.log('OK');
},
});
}
}
const columns = getColumn({
detailUrl: '/',
extraColumn: [
{
title: '操作',
render: (text, record) => {
const menu = (
<Menu>
<Menu.Item danger>修改</Menu.Item>
<Menu.Item danger>删除</Menu.Item>
<Menu.Item danger>提交</Menu.Item>
</Menu>
)
return (
<Space>
<Link to={'/'}>货源清单</Link>
<Dropdown overlay={menu}>
<a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
更多 <DownOutlined />
</a>
</Dropdown>
<Link to={`memberCenter/material/pendingAdd/edit?id=${record.id}`}>修改</Link>
<a onClick={() => handleDelete(record)}>删除</a>
<a onClick={() => handleSubmit(record)}>提交</a>
</Space>
)
}
......@@ -75,6 +87,9 @@ const MaterialQuery = () => {
>
批量删除
</Button>
<Button>
采购选品
</Button>
</Space>
)
}
......@@ -82,7 +97,7 @@ const MaterialQuery = () => {
const handleBatchDelete = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择你要启动或冻结的物料")
message.info("请选择删除的物料")
return;
}
setLoading(true)
......
......@@ -294,7 +294,7 @@ export const propsCardSchema = (schema: ISchema): ISchema => {
"s": 1
}
},
properties: schema as ISchema
properties: schema as any
}
}
}
......
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import StandardTable from '@/components/StandardTable';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { querySchema } from '../common/searchTableSchema';
import { getEnhanceSupplierAllList } from '@/services/EnhanceV2Api';
import { Button, Card, Space } from 'antd';
import { columns } from '../common/columns';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Cascader, message, Space } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { EMPTY, fetchBrand, fetchCategoryData, fetchTreeData, useAsyncCascader } from '../common/useGetTableSearchData';
import { getProductGoodsGoodsExamineChangeList1, postProductGoodsGoodsExamineChangeBatch1 } from '@/services/ProductV2Api';
import { Link } from 'umi';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
/**
* 物料查询
*/
const formActions = createFormActions();
const querySchema = getSchema({ showStatus: false });
const MaterialQuery = () => {
const ref = useRef<any>({});
const [loading, setLoading] = useState(false)
const [selectRow, selectRowFns] = useRowSelectionTable({
customKey: 'id',
extendsSelection: {
getCheckboxProps: (record: any) => ({
disabled: record.outerStatus === 0
}),
}
});
const columns = getColumn({
detailUrl: '/memberCenter/material/pendingExamI/detail',
extraColumn: [
{
title: '操作',
render: (text, record) => {
return (
<Space>
<Link to={`/memberCenter/material/pendingExamI/detail?id=${record.id}`}>修改</Link>
</Space>
)
}
}
]
})
const controllerBtns = () => {
return (
<Space>
<Button
type="primary"
onClick={handleBatchSuccess}
loading={loading}
>
批量审核通过
</Button>
......@@ -41,20 +58,42 @@ const MaterialQuery = () => {
)
}
const handleBatchFrozen = async () => {
const handleBatchSuccess = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择删除的物料")
return;
}
setLoading(true)
try {
const { data, code } = await postProductGoodsGoodsExamineChangeBatch1({ idList: selectedRowKeys })
if (code === 1000) {
ref.current.reload()
}
} catch(e) {}
finally {
setLoading(false);
}
}
const handleSearch = (values: any) => {
// const searchData = onFormatSearchData(values)
// ref.current.reload(searchData)
const formatMaterialGroupId = values.materialGroupId && values.materialGroupId.length > 0
? { materialGroupId: values.materialGroupId?.pop() }
: { }
const result = { ...values, ...formatMaterialGroupId }
ref.current.reload(result)
};
const fetchListData = async () => {
return {
totalCount: 0,
data: [],
const fetchListData = async (params) => {
try {
const { data, code } = await getProductGoodsGoodsExamineChangeList1(params);
if (code === 1000) {
return data;
}
return EMPTY
} catch(e) {
return EMPTY
}
}
......@@ -71,19 +110,18 @@ const MaterialQuery = () => {
}}
columns={columns}
currentRef={ref}
fetchTableData={() => fetchListData()}
fetchTableData={fetchListData}
controlRender={
<NiceForm
components={{ controllerBtns }}
components={{ controllerBtns, Cascader }}
schema={querySchema}
actions={formActions}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'no', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
useStateFilterSearchLinkageEffect($, actions, 'code', FORM_FILTER_PATH);
useAsyncCascader('materialGroupId', fetchTreeData)
useAsyncCascader('categoryId', fetchCategoryData)
useAsyncSelect('brandId', fetchBrand, ["name", "id"])
}}
/>
}
......
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import StandardTable from '@/components/StandardTable';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { querySchema } from '../common/searchTableSchema';
import { getEnhanceSupplierAllList } from '@/services/EnhanceV2Api';
import { Button, Card, Space } from 'antd';
import { columns } from '../common/columns';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Cascader, message, Space } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { EMPTY, fetchBrand, fetchCategoryData, fetchTreeData, useAsyncCascader } from '../common/useGetTableSearchData';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { getProductGoodsGoodsExamineChangeList2, postProductGoodsGoodsExamineChangeBatch2 } from '@/services/ProductV2Api';
import { Link } from 'umi';
/**
* 物料查询
*/
const formActions = createFormActions();
const querySchema = getSchema({ showStatus: false });
const MaterialQuery = () => {
const ref = useRef<any>({});
const [loading, setLoading] = useState(false)
const [selectRow, selectRowFns] = useRowSelectionTable({
customKey: 'id',
extendsSelection: {
getCheckboxProps: (record: any) => ({
disabled: record.outerStatus === 0
}),
}
});
const columns = getColumn({
detailUrl: '/memberCenter/material/pendingExamII/detail',
extraColumn: [
{
title: '操作',
render: (text, record) => {
return (
<Space>
<Link to={`/memberCenter/material/pendingExamII/detail?id=${record.id}`}>修改</Link>
</Space>
)
}
}
]
})
const controllerBtns = () => {
return (
<Space>
<Button
type="primary"
onClick={handleBatchSuccess}
loading={loading}
>
批量审核通过
</Button>
......@@ -41,20 +59,43 @@ const MaterialQuery = () => {
)
}
const handleBatchFrozen = async () => {
const handleBatchSuccess = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择批量审核的物料")
return;
}
setLoading(true)
try {
const { data, code } = await postProductGoodsGoodsExamineChangeBatch2({ idList: selectedRowKeys })
if (code === 1000) {
ref.current.reload()
}
} catch(e) {}
finally {
setLoading(false);
}
}
const handleSearch = (values: any) => {
// const searchData = onFormatSearchData(values)
// ref.current.reload(searchData)
const formatMaterialGroupId = values.materialGroupId && values.materialGroupId.length > 0
? { materialGroupId: values.materialGroupId?.pop() }
: { }
const result = { ...values, ...formatMaterialGroupId }
ref.current.reload(result)
};
const fetchListData = async () => {
return {
totalCount: 0,
data: [],
const fetchListData = async (params) => {
try {
const { data, code } = await getProductGoodsGoodsExamineChangeList2(params);
if (code === 1000) {
return data;
}
return EMPTY
} catch(e) {
return EMPTY
}
}
......@@ -71,19 +112,18 @@ const MaterialQuery = () => {
}}
columns={columns}
currentRef={ref}
fetchTableData={() => fetchListData()}
fetchTableData={fetchListData}
controlRender={
<NiceForm
components={{ controllerBtns }}
components={{ controllerBtns, Cascader }}
schema={querySchema}
actions={formActions}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'no', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
useStateFilterSearchLinkageEffect($, actions, 'code', FORM_FILTER_PATH);
useAsyncCascader('materialGroupId', fetchTreeData)
useAsyncCascader('categoryId', fetchCategoryData)
useAsyncSelect('brandId', fetchBrand, ["name", "id"])
}}
/>
}
......
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import StandardTable from '@/components/StandardTable';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { querySchema } from '../common/searchTableSchema';
import { getEnhanceSupplierAllList } from '@/services/EnhanceV2Api';
import { Button, Card, Space } from 'antd';
import { columns } from '../common/columns';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Cascader, message, Space } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { Link } from 'umi';
import { getProductGoodsGoodsExamineList1, postProductGoodsGoodsExamineBatch1 } from '@/services/ProductV2Api';
import { EMPTY, fetchBrand, fetchCategoryData, fetchTreeData, useAsyncCascader } from '../common/useGetTableSearchData';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
/**
* 物料查询
*/
const formActions = createFormActions();
const querySchema = getSchema({ showStatus: false });
const MaterialQuery = () => {
const ref = useRef<any>({});
const [loading, setLoading] = useState(false);
const [selectRow, selectRowFns] = useRowSelectionTable({
customKey: 'id',
extendsSelection: {
getCheckboxProps: (record: any) => ({
disabled: record.outerStatus === 0
}),
}
});
const columns = getColumn({
detailUrl: '/memberCenter/material/pendingExamI/detail',
extraColumn: [
{
title: '操作',
render: (text, record) => {
return (
<Space>
<Link to={`/memberCenter/material/pendingExamI/detail?id=${record.id}`}>修改</Link>
</Space>
)
}
}
]
})
const controllerBtns = () => {
return (
<Space>
<Button
type="primary"
onClick={handleBatchSuccess}
loading={loading}
>
批量审核通过
</Button>
......@@ -41,20 +58,42 @@ const MaterialQuery = () => {
)
}
const handleBatchFrozen = async () => {
const handleBatchSuccess = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择删除的物料")
return;
}
setLoading(true)
try {
const { data, code } = await postProductGoodsGoodsExamineBatch1({ idList: selectedRowKeys })
if (code === 1000) {
ref.current.reload()
}
} catch(e) {}
finally {
setLoading(false);
}
}
const handleSearch = (values: any) => {
// const searchData = onFormatSearchData(values)
// ref.current.reload(searchData)
const formatMaterialGroupId = values.materialGroupId && values.materialGroupId.length > 0
? { materialGroupId: values.materialGroupId?.pop() }
: { }
const result = { ...values, ...formatMaterialGroupId }
ref.current.reload(result)
};
const fetchListData = async () => {
return {
totalCount: 0,
data: [],
const fetchListData = async (params) => {
try {
const { data, code } = await getProductGoodsGoodsExamineList1(params);
if (code === 1000) {
return data;
}
return EMPTY
} catch(e) {
return EMPTY
}
}
......@@ -71,19 +110,18 @@ const MaterialQuery = () => {
}}
columns={columns}
currentRef={ref}
fetchTableData={() => fetchListData()}
fetchTableData={fetchListData}
controlRender={
<NiceForm
components={{ controllerBtns }}
components={{ controllerBtns, Cascader }}
schema={querySchema}
actions={formActions}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'no', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
useStateFilterSearchLinkageEffect($, actions, 'code', FORM_FILTER_PATH);
useAsyncCascader('materialGroupId', fetchTreeData)
useAsyncCascader('categoryId', fetchCategoryData)
useAsyncSelect('brandId', fetchBrand, ["name", "id"])
}}
/>
}
......
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import StandardTable from '@/components/StandardTable';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { querySchema } from '../common/searchTableSchema';
import { getEnhanceSupplierAllList } from '@/services/EnhanceV2Api';
import { Button, Card, Space } from 'antd';
import { columns } from '../common/columns';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Cascader, message, Space } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { Link } from 'umi';
import { getProductGoodsGoodsExamineList2, postProductGoodsGoodsExamineBatch2 } from '@/services/ProductV2Api';
import { EMPTY, fetchBrand, fetchCategoryData, fetchTreeData, useAsyncCascader } from '../common/useGetTableSearchData';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
/**
* 物料查询
*/
const formActions = createFormActions();
const querySchema = getSchema({ showStatus: false });
const MaterialQuery = () => {
const ref = useRef<any>({});
const [loading, setLoading] = useState(false);
const [selectRow, selectRowFns] = useRowSelectionTable({
customKey: 'id',
extendsSelection: {
getCheckboxProps: (record: any) => ({
disabled: record.outerStatus === 0
}),
}
});
const columns = getColumn({
detailUrl: '/memberCenter/material/pendingExamII/detail',
extraColumn: [
{
title: '操作',
render: (text, record) => {
return (
<Space>
<Link to={`/memberCenter/material/pendingExamII/detail?id=${record.id}`}>修改</Link>
</Space>
)
}
}
]
})
const controllerBtns = () => {
return (
<Space>
<Button
type="primary"
onClick={handleBatchSuccess}
loading={loading}
>
批量审核通过
</Button>
......@@ -41,20 +57,43 @@ const MaterialQuery = () => {
)
}
const handleBatchFrozen = async () => {
const handleBatchSuccess = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择批量审核的物料")
return;
}
setLoading(true)
try {
const { data, code } = await postProductGoodsGoodsExamineBatch2({ idList: selectedRowKeys })
if (code === 1000) {
ref.current.reload()
}
} catch(e) {}
finally {
setLoading(false);
}
}
const handleSearch = (values: any) => {
// const searchData = onFormatSearchData(values)
// ref.current.reload(searchData)
const formatMaterialGroupId = values.materialGroupId && values.materialGroupId.length > 0
? { materialGroupId: values.materialGroupId?.pop() }
: { }
const result = { ...values, ...formatMaterialGroupId }
ref.current.reload(result)
};
const fetchListData = async () => {
return {
totalCount: 0,
data: [],
const fetchListData = async (params) => {
try {
const { data, code } = await getProductGoodsGoodsExamineList2(params);
if (code === 1000) {
return data;
}
return EMPTY
} catch(e) {
return EMPTY
}
}
......@@ -71,19 +110,18 @@ const MaterialQuery = () => {
}}
columns={columns}
currentRef={ref}
fetchTableData={() => fetchListData()}
fetchTableData={fetchListData}
controlRender={
<NiceForm
components={{ controllerBtns }}
components={{ controllerBtns, Cascader }}
schema={querySchema}
actions={formActions}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'no', FORM_FILTER_PATH);
// useAsyncInitSelect(
// ['innerStatus', 'outerStatus'],
// fetchSelectOptions,
// );
useStateFilterSearchLinkageEffect($, actions, 'code', FORM_FILTER_PATH);
useAsyncCascader('materialGroupId', fetchTreeData)
useAsyncCascader('categoryId', fetchCategoryData)
useAsyncSelect('brandId', fetchBrand, ["name", "id"])
}}
/>
}
......
import React from 'react';
import React, { useMemo } from 'react';
import AnchorPage from '@/components/AnchorPage';
import AuditProcess from '@/components/AuditProcess';
import MellowCard from '@/components/MellowCard';
......@@ -6,12 +6,33 @@ import useGetDetailCommon from '../common/useGetDetailCommon';
import { Card, Space, Table } from 'antd';
import CustomizeColumn from '@/components/CustomizeColumn';
import ImageList from '../components/imageList'
import { usePageStatus } from '@/hooks/usePageStatus';
import useGetInitialValueDetail from '../common/useGetInitialValueDetail';
import { getProductGoodsGetGoodsProcessDetail, GetProductGoodsGetGoodsProcessDetailResponse, GetProductGoodsGetGoodsResponse, getProductGoodsGetMaterInnerLogList, GetProductGoodsGetMaterInnerLogListResponse } from '@/services/ProductV2Api';
/**
* 详情
*/
const Detail = () => {
const { anchorHeader, auditProcess, basicInfoList, tableColumn, recordColumn } = useGetDetailCommon<null>({initialValue: null})
const { id } = usePageStatus();
const { initialValue, record } = useGetInitialValueDetail<GetProductGoodsGetGoodsProcessDetailResponse, GetProductGoodsGetMaterInnerLogListResponse>({
id: id,
api: getProductGoodsGetGoodsProcessDetail,
logApi: getProductGoodsGetMaterInnerLogList
})
const { anchorHeader, auditProcess, basicInfoList, tableColumn, recordColumn, properties } = useGetDetailCommon<GetProductGoodsGetGoodsResponse | null>({initialValue: initialValue})
console.log(auditProcess);
const urls = useMemo(() => {
if (initialValue) {
return initialValue.urls
}
return []
}, [initialValue])
const logs = useMemo(() => {
return record
}, [record])
return (
<AnchorPage
......@@ -25,7 +46,7 @@ const Detail = () => {
/>
<Space>
<CustomizeColumn
id="detail"
id="basic"
data={basicInfoList}
title={"基本信息"}
column={2}
......@@ -33,30 +54,30 @@ const Detail = () => {
</Space>
<Space>
<CustomizeColumn
id="detail1"
data={basicInfoList}
id="properties"
data={properties}
title={"物料型号"}
column={2}
/>
</Space>
<div style={{marginTop: '16px'}}>
<div style={{marginTop: '16px'}} id="images">
<Card title="物料图片" bodyStyle={{paddingTop: '0'}}>
<ImageList />
<ImageList imageUrls={initialValue?.goodsPic} />
</Card>
</div>
<div style={{marginTop: '16px'}}>
<div style={{marginTop: '16px'}} id="files">
<Card title="附件">
<Table
columns={tableColumn}
dataSource={[]}
dataSource={urls}
/>
</Card>
</div>
<div style={{marginTop: '16px'}}>
<Card title="附件">
<div style={{marginTop: '16px'}} id="log">
<Card title="流转记录">
<Table
columns={recordColumn}
dataSource={[]}
dataSource={logs}
/>
</Card>
</div>
......
......@@ -4,21 +4,24 @@ import { PageHeaderWrapper } from '@ant-design/pro-layout';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { querySchema } from '../common/searchTableSchema';
import { Button, Card, Space, Cascader, message, Menu, Dropdown } from 'antd';
import { getSchema } from '../common/searchTableSchema';
import { Button, Card, Space, Cascader, message, Menu, Dropdown, Modal } from 'antd';
import { getColumn } from '../common/columns';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { getProductGoodsGetMaterialList, GetProductGoodsGetMaterialListRequest, postProductGoodsFreezeOrEnableGoodsBatch } from '@/services/ProductV2Api';
import { getProductCommodityGoodsUsing, getProductGoodsGetMaterialList, GetProductGoodsGetMaterialListRequest, postProductGoodsFreezeOrEnableGoods, postProductGoodsFreezeOrEnableGoodsBatch } from '@/services/ProductV2Api';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { useAsyncCascader, fetchBrand, fetchStatus, fetchCategoryData, fetchTreeData, EMPTY } from '../common/useGetTableSearchData';
import { Link } from 'umi';
import { DownOutlined } from '@ant-design/icons';
import FrozonMadal from '../components/frozonMadal';
import { FROZEN } from '@/constants/material';
/**
* 物料查询
*/
const formActions = createFormActions();
const querySchema = getSchema({ showStatus: true });
export type SearchParams = Omit<GetProductGoodsGetMaterialListRequest, 'materialGroupId'> & {
materialGroupId: string[],
......@@ -28,31 +31,55 @@ export type SearchParams = Omit<GetProductGoodsGetMaterialListRequest, 'material
const MaterialQuery = () => {
const ref = useRef<any>({});
const [loading, setLoading] = useState<boolean>(false);
const [visible, setVisible] = useState<boolean>(false);
const [activeItem, setActiveItem] = useState(null)
const [isBatch, setIsBatch] = useState(false);
const [selectRow, selectRowFns] = useRowSelectionTable({
customKey: 'id',
// extendsSelection: {
// getCheckboxProps: (record: any) => ({
// disabled: record.outerStatus === 0
// }),
// }
});
const handleFrozonOrEnable = async (params: { id: string; interiorState: number }) => {
if (params.interiorState === FROZEN) {
onFrozonOrEnable({ goodsId: +params.id, status: 1 });
return;
}
const { data, code } = await getProductCommodityGoodsUsing({ idList: [params.id] });
if (code !== 1000) {
return;
}
if (data) {
message.info("物料已关联商品,无法进行冻结");
return;
}
setIsBatch(false);
setActiveItem(params);
setVisible(true);
}
const columns = getColumn({
detailUrl: '/',
detailUrl: '/memberCenter/material/query/detail',
extraColumn: [
{
dataIndex: '操作',
render: (text, record) => {
const menu = (
<Menu>
<Menu.Item danger>冻结</Menu.Item>
<Menu.Item danger>变更</Menu.Item>
<Menu.Item danger>价格库</Menu.Item>
<Menu.Item
onClick={() => handleFrozonOrEnable({ interiorState: record.interiorState, id: record.id })}
>
{ record.interiorState > FROZEN ? "冻结" : '启用'}
</Menu.Item>
{
record.interiorState !== FROZEN && (
<Menu.Item>变更</Menu.Item>
)
}
<Menu.Item>价格库</Menu.Item>
</Menu>
)
return (
<Space>
<Link to={'/'}>货源清单</Link>
<Link to={{pathname: `/memberCenter/material/query/sourceList`, query: { id: record.id }, state: { name: record.name }}}>货源清单</Link>
<Dropdown overlay={menu}>
<a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
更多 <DownOutlined />
......@@ -65,13 +92,28 @@ const MaterialQuery = () => {
]
})
const handleBatchForFrozen = async () => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
const { data, code } = await getProductCommodityGoodsUsing({ idList: selectedRowKeys });
if (code !== 1000) {
return;
}
if (data) {
message.info("物料已关联商品,无法进行冻结");
return;
}
setVisible(true);
setIsBatch(true);
}
const controllerBtns = () => {
return (
<Space>
<Button
type="primary"
loading={loading}
onClick={() => handleBatchFrozen(0)}
onClick={handleBatchForFrozen}
>
批量冻结
</Button>
......@@ -85,14 +127,17 @@ const MaterialQuery = () => {
)
}
const handleFrozonOrEnable = async (params: { status: number, goodsId: number, freezeReason: string }) => {
const onFrozonOrEnable = async (params: { status: number, goodsId: number, freezeReason?: string }) => {
const { freezeReason, ...rest } = params
const formatData = params.status === 0
? params
: rest
const { data, code } = await postProductGoodsFreezeOrEnableGoodsBatch(formatData);
const { data, code } = await postProductGoodsFreezeOrEnableGoods(formatData);
setVisible(false);
if (code === 1000) {
ref.current.reload()
// ref.current.reload()
formActions.submit()
}
}
......@@ -100,17 +145,31 @@ const MaterialQuery = () => {
* 冻结 0, 启动 1
* @param status
*/
const handleBatchFrozen = async (status: 0 | 1) => {
const handleBatchFrozen = async (status: 0 | 1, reason?: string) => {
const selectedRowKeys = selectRowFns.selectedRowKeys;
if (selectedRowKeys.length === 0) {
message.info("请选择你要启动或冻结的物料")
return;
}
const defaultData = {
goodsId: selectedRowKeys,
status: status
}
const postData = status === 1
? defaultData
: {
...defaultData,
freezeReason: reason
}
setLoading(true)
try {
const { data, code } = await postProductGoodsFreezeOrEnableGoodsBatch({ goodsId: selectedRowKeys, status: status })
const { data, code } = await postProductGoodsFreezeOrEnableGoodsBatch(postData)
if (code === 1000) {
ref.current.reload()
// ref.current.reload()
formActions.submit()
}
} catch(e) {}
finally {
......@@ -140,6 +199,13 @@ const MaterialQuery = () => {
}
}
const handleFrozon = (value) => {
if (isBatch) {
handleBatchFrozen(0, value.reason)
}
onFrozonOrEnable({ status: 0, goodsId: activeItem.id, freezeReason: value.reason })
}
return (
<PageHeaderWrapper
title={"物料"}
......@@ -171,6 +237,12 @@ const MaterialQuery = () => {
}
/>
</Card>
<FrozonMadal
visible={visible}
onCancel={() => setVisible(false)}
title="冻结"
onSubmit={handleFrozon}
/>
</PageHeaderWrapper>
)
}
......
.addition {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border: 1px solid #EDEEEF;
border-radius: 4px;
padding: 4px;
background-color: #EDEEEF;
color: #5C626A;
margin-top: 12px;
cursor: pointer;
.text {
margin-left: 4px;
}
}
\ No newline at end of file
import AnchorPage from '@/components/AnchorPage';
import NiceForm from '@/components/NiceForm';
import { ISchema } from '@formily/antd';
import { Card } from 'antd';
import React from 'react';
import { createFormActions, FormPath, ISchema } from '@formily/antd';
import { Button, Card, message, Space } from 'antd';
import React, { useEffect, useState } from 'react';
import { Input, ArrayTable } from '@formily/antd-components'
import { PlusOutlined } from '@ant-design/icons';
import styles from './sourceList.less'
import TableModal from '@/pages/member/components/TableModal';
import { getProductGoodsGetGoodsSourceList, postProductGoodsSubmitGoodsSourceList } from '@/services/ProductV2Api';
import { usePageStatus } from '@/hooks/usePageStatus';
import { history } from 'umi';
import { getMemberAbilityMaintenanceSubOrdinateMemberList } from '@/services/MemberV2Api';
const formActions = createFormActions();
const anchorHeader = [
{
name: '货源清单',
key: 'source-list',
}
]
const DEFAULT_RETURN_DATA = {
totalCount: 0,
data: []
}
const SourceList = () => {
const anchorHeader = [
{
name: '货源清单',
key: 'source-list',
}
]
const { id } = usePageStatus();
console.log(history);
const { location } = history;
const { name = ''} = location?.state || { name: ''}
const [visible, setVisible] = useState(false);
const [initialValue, setInitialValue] = useState<any>(null);
const handleEdit = (index: number) => {
console.log(index);
formActions.setFieldState(`datas.${index}.*(!id,memberName)`, (state) => {
FormPath.setIn(state, 'editable', true);
})
}
const schema: ISchema = {
type: 'object',
properties: {
......@@ -21,7 +50,8 @@ const SourceList = () => {
"x-component": 'mega-layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 12
wrapperCol: 12,
labelAlign: 'left',
},
properties: {
name: {
......@@ -30,13 +60,29 @@ const SourceList = () => {
},
}
},
urls: {
addition: {
'type': 'object',
'x-component': 'Children',
'x-component-props': {
children: '{{renderAddition}}'
}
},
datas: {
type: 'array',
'x-component': 'ArrayTable',
"x-component-props": {
// operations: false,
// renderAddition: '{{renderAddition}}',
// renderRemove: '{{renderListTableRemove}}',
renderAddition: () => null,
renderRemove: () => null,
renderMoveUp: () => null,
renderMoveDown: () => null,
renderExtraOperations: (index: number) => {
return (
<Space>
<a onClick={() => handleEdit(index)}>编辑</a>
<a>删除</a>
</Space>
)
},
operations: {
title: `操作`
},
......@@ -53,12 +99,47 @@ const SourceList = () => {
memberName: {
title: '供应会员',
type: 'string',
"x-rules": [
{
required: true,
message: '请填写备注',
}
]
editable: false,
},
goodsNo: {
title: '供应商物料编号',
type: 'string',
editable: false,
},
userName: {
title: '联系人',
type: 'string',
editable: false,
},
phone: {
title: '联系电话',
type: 'string',
editable: false,
},
manufactory: {
title: '生产厂家',
type: 'string',
editable: false,
},
origin: {
title: '产地',
type: 'string',
editable: false,
},
departure: {
title: '起运地',
type: 'string',
editable: false,
},
deliveryCycle: {
title: '到货周期',
type: 'string',
editable: false,
},
deliveryMethod: {
title: '交货方式',
type: 'string',
editable: false,
}
}
}
......@@ -66,20 +147,179 @@ const SourceList = () => {
}
}
console.log(initialValue, "initialValue")
const handleOpenModal = () => {
setVisible(true);
}
useEffect(() => {
async function getInitialValue() {
const { data, code } = await getProductGoodsGetGoodsSourceList({ id: id } as any);
if (code === 1000) {
setInitialValue({ name: name, datas: data })
}
return []
}
getInitialValue()
}, [])
const renderAddition = () => (
<div className={styles.addition} onClick={handleOpenModal}>
<PlusOutlined />
<span className={styles.text}>新增附件信息</span>
</div>
)
const handleFetchData = async (params) => {
const { data, code } = await getMemberAbilityMaintenanceSubOrdinateMemberList(params);
if (code === 1000) {
return data
}
return DEFAULT_RETURN_DATA as any
}
const columns = [
{
title: '供应商id',
dataIndex: 'id',
},
{
title: '供应商名称',
dataIndex: 'name'
}
];
const suppilerSchema = {
type: 'object',
properties: {
layout: {
type: 'object',
"x-component": 'mega-layout',
properties: {
code: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '供应商名称',
align: 'flex-left',
advanced: false
},
},
}
},
}
}
const handleOnOk = (selectRow, selectRowRecord) => {
const { datas = [] } = initialValue || { datas: [] };
const currentMemberIdAndRoleIdList = datas.map((_item) => {
return `${_item.memberId}_${_item.roleId}`;
})
/** 从原数组中如果没有查到当前值,那么就代表他是新增进来的 */
/**
* 比如原数组 [1_1, 1_2]
* 勾选数组 [1_1, 1_2, 1_3],
* 那么 [1_3] 就是新增的
*/
/** 获取从元素组中没有勾选则数据 */
/**
* 比如原数组 [1_1, 1_2]
* 勾选数组 [1_1],
* 那么 [1_3] 就是新增的
*/
const rowRecord = selectRowRecord;
const addList = [];
const deleteList = [];
selectRowRecord.forEach((_item) => {
if (!currentMemberIdAndRoleIdList.includes(`${_item.memberId}_${_item.roleId}`)) {
addList.push(_item);
} else {
deleteList.push(_item)
}
})
// const addList = selectRowRecord.filter((_item) => !currentMemberIdAndRoleIdList.includes(`${_item.memberId}_${_item.roleId}`));
// const deleteList = selectRowRecord.filter((_item) => currentMemberIdAndRoleIdList.includes(`${_item.memberId}_${_item.roleId}`));
const newDataSource = currentMemberIdAndRoleIdList.concat(addList).map((_item) => {
return {
..._item,
status: _item.status ?? 1
}
});
setInitialValue({
...initialValue,
datas: newDataSource,
})
formActions.setFieldValue('datas', newDataSource.filter((_item) => _item.status))
setVisible(false)
console.log(selectRowRecord, selectRow);
}
const handleSubmit = async (value: any) => {
const { datas } = value;
const postData = datas.map((_item) => {
return {
..._item,
}
})
const { data, code } = await postProductGoodsSubmitGoodsSourceList({ goodsSupplyListRequests: postData } as any);
if (code === 1000) {
message.success('保存成功')
}
}
return (
<AnchorPage
title={"货源清单"}
anchors={anchorHeader}
// extra={headExtra && headExtra(detailInfo, returnAddress, exchangeAddress)}
extra={
<Button onClick={() => formActions.submit}>提交</Button>
}
>
<Card title="货源清单">
<NiceForm
expressionScope={{
renderAddition: renderAddition(),
}}
value={initialValue}
onSubmit={handleSubmit}
actions={formActions}
schema={schema}
components={{
ArrayTable,
}}
/>
</Card>
<TableModal
modalType='Drawer'
visible={visible}
onClose={() => setVisible(false)}
title={"选择供应商"}
columns={columns}
schema={suppilerSchema}
onOk={handleOnOk}
fetchData={handleFetchData}
tableProps={{
rowKey: (record) => `${record.id}`,
}}
effects={($, actions) => {
}}
// components={{Cascader}}
mode={"checkbox"}
// value={value}
value={initialValue?.datas?.filter((_item) => _item.status)}
/>
</AnchorPage>
)
}
......
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