Commit 9e77a786 authored by 前端-许佳敏's avatar 前端-许佳敏

使用formily重写仓位模块

parent c3b887ed
...@@ -25,3 +25,4 @@ ...@@ -25,3 +25,4 @@
config/base.config.json config/base.config.json
/src/services/index.ts /src/services/index.ts
.vscode
const MAIN_COLOR = '#00B37A'
const MAIN_FONT_BOLD_COLOR = '#172B4D'
const MAIN_FONT_TINY_COLOR = '#6B778C'
export default { export default {
'@primary-color': '#00B37A', '@primary-color': MAIN_COLOR,
// 公共padding变量 // 公共padding变量
'@padding-lg': '24px', '@padding-lg': '24px',
...@@ -13,4 +17,11 @@ export default { ...@@ -13,4 +17,11 @@ export default {
'@margin-sm': '12px', '@margin-sm': '12px',
'@margin-xs': '8px', '@margin-xs': '8px',
'@margin-xss': '4px', '@margin-xss': '4px',
// tabs
'tabs-card-active-color': MAIN_FONT_BOLD_COLOR,
'tabs-highlight-color': MAIN_FONT_BOLD_COLOR,
'tabs-hover-color': MAIN_FONT_BOLD_COLOR,
'tabs-active-color': MAIN_FONT_BOLD_COLOR,
'tabs-card-head-background': '#fff',
} }
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
"dependencies": { "dependencies": {
"@ant-design/icons": "^4.2.1", "@ant-design/icons": "^4.2.1",
"@ant-design/pro-layout": "^5.0.16", "@ant-design/pro-layout": "^5.0.16",
"@formily/antd": "^1.2.8", "@formily/antd": "^1.2.10",
"@formily/antd-components": "^1.2.8", "@formily/antd-components": "^1.2.10",
"@umijs/preset-react": "1.x", "@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0", "@umijs/test": "^3.2.0",
"bizcharts": "^4.0.7", "bizcharts": "^4.0.7",
......
import React, { useState } from 'react'
import { Input, Space, Button, Table } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
const MultTable = (props) => {
const { columns } = props.props['x-component-props']
const value = props.value || []
return (
<div style={{width: '100%'}}>
<Button block icon={<PlusOutlined/>} type='dashed'>选择指定会员</Button>
<Table
rowKey='id'
columns={columns}
dataSource={value}
/>
</div>
)
}
MultTable.defaultProps = {}
MultTable.isFieldComponent = true;
export default MultTable
\ No newline at end of file
import React, { useState } from 'react' import React, { useState } from 'react'
import { Input, Space, Button } from 'antd' import { Input, Space, Button } from 'antd'
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons'
import { useFieldState, FormPath } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
const Submit = (props) => { const Submit = (props) => {
return ( return (
......
...@@ -9,6 +9,7 @@ import Search from './components/Search'; ...@@ -9,6 +9,7 @@ import Search from './components/Search';
import Submit from './components/Submit'; import Submit from './components/Submit';
import Text from './components/Text'; import Text from './components/Text';
import CardCheckBox from './components/CardCheckBox'; import CardCheckBox from './components/CardCheckBox';
import MultTable from './components/MultTable';
export interface NiceFormProps extends IAntdSchemaFormProps { export interface NiceFormProps extends IAntdSchemaFormProps {
} }
...@@ -23,7 +24,8 @@ const NiceForm:React.FC<NiceFormProps> = (props) => { ...@@ -23,7 +24,8 @@ const NiceForm:React.FC<NiceFormProps> = (props) => {
Search, Search,
Submit, Submit,
Text, Text,
CardCheckBox CardCheckBox,
MultTable
} }
const defineComponents = Object.assign(customComponents, components) const defineComponents = Object.assign(customComponents, components)
......
...@@ -30,4 +30,10 @@ ...@@ -30,4 +30,10 @@
margin-right: 24px; margin-right: 24px;
} }
} }
// 设置formitem的*号到字段label前
.ant-form-item-label > label.ant-form-item-required::before {
order: 10;
margin-left: -6px;
}
} }
\ No newline at end of file
...@@ -46,8 +46,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => { ...@@ -46,8 +46,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
settings, settings,
location, location,
} = props; } = props;
console.log(props)
const defaultSetting: Settings = { const defaultSetting: Settings = {
navTheme: 'dark', navTheme: 'dark',
// 拂晓蓝 // 拂晓蓝
......
...@@ -14,6 +14,11 @@ import { StandardTable } from 'god' ...@@ -14,6 +14,11 @@ import { StandardTable } from 'god'
import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableController'; import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableController';
import ReutrnEle from '@/components/ReturnEle'; import ReutrnEle from '@/components/ReturnEle';
import styles from './index.less' import styles from './index.less'
import NiceForm from '@/components/NiceForm'
import { repositDetailSchema } from './schema'
import { createFormActions } from '@formily/antd'
import EyePreview from '@/components/EyePreview'
import { findItemAndDelete } from '@/utils'
const {Item}:any = Form const {Item}:any = Form
const { Option } = Select const { Option } = Select
...@@ -92,6 +97,8 @@ const fetchData = (params:any) => { ...@@ -92,6 +97,8 @@ const fetchData = (params:any) => {
}) })
} }
const addSchemaAction = createFormActions()
const AddRepository:React.FC<{}> = (props) => { const AddRepository:React.FC<{}> = (props) => {
const ref = useRef({}) const ref = useRef({})
const [form] = Form.useForm() const [form] = Form.useForm()
...@@ -274,16 +281,55 @@ const AddRepository:React.FC<{}> = (props) => { ...@@ -274,16 +281,55 @@ const AddRepository:React.FC<{}> = (props) => {
} }
const onNumberChange = (v: any) => { const onNumberChange = (v: any) => {
console.log(v)
setInputSliderValue(v) setInputSliderValue(v)
} }
const handleSubmit = (values) => {
console.log(values)
}
const handleDeleteTable = (id) => {
const value = addSchemaAction.getFieldValue('applyMember')
addSchemaAction.setFieldValue('applyMember', findItemAndDelete(value, id))
}
const tableColumns = [
{ dataIndex: 'id', title: 'ID' },
{ dataIndex: 'name', title: '会员名称', render: (_, record) => <EyePreview url={`/memberCenter/memberAbility/manage/addMember?id=${record.id}&preview=1`}/> },
{ dataIndex: 'type', title: '会员类型' },
{ dataIndex: 'ctl', title: '操作', render: (_, record) => <Button type='link' onClick={() => handleDeleteTable(record.id)}>删除</Button> }
]
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回"/>}
title="新建仓位"
extra={[
<Button key="1" onClick={() => addSchemaAction.submit()} type="primary" icon={<SaveOutlined />}>
保存
</Button>,
]}
>
<Card className=''>
<NiceForm
expressionScope={{
tableColumns
}}
onSubmit={handleSubmit}
actions={addSchemaAction}
schema={repositDetailSchema}
/>
</Card>
</PageHeaderWrapper>
)
return (<PageHeaderWrapper return (<PageHeaderWrapper
onBack={() => history.goBack()} onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回"/>} backIcon={<ReutrnEle description="返回"/>}
title="新建仓位" title="新建仓位"
extra={[ extra={[
<Button key="1" type="primary" icon={<SaveOutlined />}> <Button key="1" onClick={handleSubmit} type="primary" icon={<SaveOutlined />}>
保存 保存
</Button>, </Button>,
]} ]}
......
import React, { ReactNode, useRef } from 'react' import React, { ReactNode, useRef, useState } from 'react'
import { history } from 'umi' import { history } from 'umi'
import { Button, Popconfirm, Card } from 'antd' import { Button, Popconfirm, Card, Row, Col, Dropdown, Input, Select, Space } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout' import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { import {
PlusOutlined, PlusOutlined,
PlayCircleOutlined, PlayCircleOutlined,
EyeOutlined, EyeOutlined,
DownOutlined,
CaretUpOutlined,
CaretDownOutlined,
} from '@ant-design/icons' } from '@ant-design/icons'
import { StandardTable } from 'god' import { StandardTable } from 'god'
import { ColumnType } from 'antd/lib/table/interface' import { ColumnType } from 'antd/lib/table/interface'
import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableController' import { IFormFilter, IButtonFilter } from 'god/dist/src/standard-table/TableController'
import EyePreview from '@/components/EyePreview'
import StatusSwitch from '@/components/StatusSwitch'
import NiceForm from '@/components/NiceForm'
import { createFormActions, FormEffectHooks } from '@formily/antd'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { repositSchema } from './schema'
import { PublicApi } from '@/services/api'
const data = [ const formActions = createFormActions()
{
key: '1',
reposName: '进口头层黄牛皮荔枝纹/红色/XL-渠道商城-所有渠道',
producName: '进口头层黄牛皮荔枝纹/红色/XL',
pType: '牛皮',
brand: '天梭',
unit: '吨',
amount: '15151',
status: 1,
},
{
key: '2',
reposName: '进口头层黄牛皮荔枝纹/红色/XL-渠道商城-所有渠道',
producName: '进口头层黄牛皮荔枝纹/红色/XL',
pType: '牛皮',
brand: '卡帝乐',
unit: '吨',
amount: '15151',
status: 0,
},
]
// 模拟请求 // 模拟请求
const fetchData = (params:any) => { const fetchData = async (params:any) => {
return new Promise((resolve, reject) => { const res = await PublicApi.getWarehouseFreightSpaceList(params)
const queryResult = data.find(v => v.key === params.keywords) return res.data
setTimeout(() => {
resolve({
code: 200,
message: '',
data: queryResult ? [queryResult] : data
})
}, 1000)
})
} }
const Repositories: React.FC<{}> = () => { const Repositories: React.FC<{}> = () => {
const ref = useRef({}) const ref = useRef<any>({})
const columns: ColumnType<any>[] = [ const columns: ColumnType<any>[] = [
{ {
...@@ -63,7 +45,7 @@ const Repositories: React.FC<{}> = () => { ...@@ -63,7 +45,7 @@ const Repositories: React.FC<{}> = () => {
dataIndex: 'reposName', dataIndex: 'reposName',
align: 'center', align: 'center',
key: 'reposName', key: 'reposName',
render: (text:any, record:any) => <span className="commonPickColor" onClick={()=>handleSee(record)}>{text}&nbsp;<EyeOutlined /></span> render: (text:any, record:any) => <EyePreview url={`/repositories/viewRepository?id=${record.key}&preview=1`}>{text}</EyePreview>
}, },
{ {
title: '商品名称', title: '商品名称',
...@@ -100,21 +82,7 @@ const Repositories: React.FC<{}> = () => { ...@@ -100,21 +82,7 @@ const Repositories: React.FC<{}> = () => {
align: 'center', align: 'center',
dataIndex: 'status', dataIndex: 'status',
key: 'status', key: 'status',
render: (text: any, record:any) => { render: (text: any, record:any) => <StatusSwitch handleConfirm={()=>handleModify(record)} record={record}/>
let component: ReactNode = null
component = (
<Popconfirm
title="确定要执行这个操作?"
onConfirm={confirm}
onCancel={cancel}
okText="是"
cancelText="否"
>
<Button type="link" onClick={()=>handleModify(record)} style={record.status===1?{color:'#00B37A'}:{color:'red'}}>{record.status===1?'有效':'无效'} <PlayCircleOutlined /></Button>
</Popconfirm>
)
return component
}
}, },
{ {
title: '操作', title: '操作',
...@@ -124,7 +92,7 @@ const Repositories: React.FC<{}> = () => { ...@@ -124,7 +92,7 @@ const Repositories: React.FC<{}> = () => {
return ( return (
<> <>
{ {
record.status === 1 ? <Button type='link' onClick={()=>handleAdjust(record)}>库存调拨</Button> : '' record.state === 1 ? <Button type='link' onClick={()=>handleAdjust(record)}>库存调拨</Button> : ''
} }
</> </>
) )
...@@ -132,75 +100,6 @@ const Repositories: React.FC<{}> = () => { ...@@ -132,75 +100,6 @@ const Repositories: React.FC<{}> = () => {
} }
]; ];
const search: IFormFilter[] = [
{
type: 'Input',
value: 'keywords',
col: 4,
placeHolder: '商品ID'
},
{
type: 'Input',
value: 'name',
col: 4,
placeHolder: '商品名称'
},
{
type: 'Input',
value: 'brand',
col: 4,
placeHolder: '商品品牌'
},
{
type: 'Input',
value: 'type',
col: 4,
placeHolder: '商品品类'
},
{
type: 'Input',
value: 'repository',
col: 4,
placeHolder: '仓位名称'
},
{
type: 'Select',
value: 'status',
col: 4,
placeHolder: '仓位状态',
statusList: [{
type: 'Select',
label:'所有',
value:'0'
},{
type: 'Select',
label:'还不错',
value:'1'
},{
type: 'Select',
label:'还可以',
value:'2'
}]
},
]
const searchBarActions: IButtonFilter[] = [
{
text: '查询',
handler: () => {
console.log('查询')
}
},
{
type: 'primary',
text: '新建',
icon: <PlusOutlined />,
handler: ()=>{
history.push('/repositories/addRepository')
}
}
]
const handleSee = (record:any) => { const handleSee = (record:any) => {
console.log('see') console.log('see')
history.push(`/repositories/viewRepository?id=${record.key}`) history.push(`/repositories/viewRepository?id=${record.key}`)
...@@ -210,10 +109,6 @@ const Repositories: React.FC<{}> = () => { ...@@ -210,10 +109,6 @@ const Repositories: React.FC<{}> = () => {
console.log('confirm') console.log('confirm')
} }
const cancel = () => {
console.log('cancel')
}
const handleModify = (record: object) => { const handleModify = (record: object) => {
// 通过传入的params字符串判断是修改那种类型的数据 // 通过传入的params字符串判断是修改那种类型的数据
console.log('执行状态修改', record) console.log('执行状态修改', record)
...@@ -223,15 +118,37 @@ const Repositories: React.FC<{}> = () => { ...@@ -223,15 +118,37 @@ const Repositories: React.FC<{}> = () => {
history.push(`/memberCenter/commodityAbility/repositories/adjustRepository?id=${record.key}`) history.push(`/memberCenter/commodityAbility/repositories/adjustRepository?id=${record.key}`)
} }
const handleToAdd = () => {
history.push(`/memberCenter/commodityAbility/repositories/addRepository`)
}
return ( return (
<PageHeaderWrapper> <PageHeaderWrapper>
<Card> <Card>
<StandardTable <StandardTable
columns={columns} columns={columns}
currentRef={ref} currentRef={ref}
fetchTableData={(params:any) => fetchData(params)} tableProps={{rowKey: "key"}}
formFilters={search} fetchTableData={(params: any) => fetchData(params)}
buttonFilters={searchBarActions} controlRender={
<Row justify='space-between'>
<Col>
<Space>
<Button type='primary' onClick={handleToAdd} icon={<PlusOutlined />}>新建</Button>
</Space>
</Col>
<Col>
<NiceForm
actions={formActions}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'search', FORM_FILTER_PATH)
}}
schema={repositSchema}
/>
</Col>
</Row>
}
/> />
</Card> </Card>
</PageHeaderWrapper> </PageHeaderWrapper>
......
import React from 'react'
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import EyePreview from '@/components/EyePreview';
import { Button } from 'antd';
export const repositSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
"x-component": 'mega-layout',
properties: {
search: {
type: 'string',
"x-component": 'Search',
"x-mega-props": {
},
"x-component-props": {
placeholder: '请输入仓位名称'
}
},
[FORM_FILTER_PATH]: {
type: 'object',
"x-component": "mega-layout",
visible: false,
"x-component-props": {
inline: true
},
properties: {
productName: {
type: 'string',
"x-component-props": {
placeholder: '商品名称'
}
},
productId: {
type: 'string',
"x-component-props": {
placeholder: '商品ID'
}
},
category: {
type: 'string',
"x-component-props": {
placeholder: '请选择品类'
},
enum: []
},
brand: {
type: 'string',
"x-component-props": {
placeholder: '请选择品牌'
},
enum: []
},
submit: {
"x-component": 'Submit',
"x-component-props": {
children: '查询'
}
}
},
},
}
}
}
}
export const repositDetailSchema: ISchema = {
type: 'object',
properties: {
REPOSIT_TABS: {
type: 'object',
"x-component": "tab",
"x-component-props": {
type: 'card'
},
properties: {
"tab-1": {
"type": "object",
"x-component": "tabpane",
"x-component-props": {
"tab": "基本信息"
},
"properties": {
MEGA_LAYOUT1: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelCol: 4,
wrapperCol: 8,
labelAlign: 'left'
},
properties: {
name: {
type: 'string',
required: true,
title: '仓位名称',
"x-component-props": {
placeholder: '建议名称:商品名称+商城名称+渠道描述'
}
},
productName: {
type: 'string',
title: '商品名称',
required: true
},
warehouseId: {
type: 'string',
title: '仓库名称',
enum: []
},
itemNo: {
type: 'string',
"x-component": 'Text',
title: '对应货品',
default: '暂无'
},
inventory: {
type: 'number',
"x-component": "CustomSlider",
required: true,
"x-component-props": {
min: 0,
max: 200
},
title: '分配仓位库存',
},
inventoryDeductWay: {
type: 'radio',
title: '库存扣减方式',
required: true,
enum: [
{
label: '按仓位随机扣减',
value: 1
},
{
label: '按仓库位置远近扣除',
value: 2
}
],
default: 1
}
}
}
}
},
"tab-2": {
"type": "object",
"x-component": "tabpane",
"x-component-props": {
"tab": "适用商城"
},
"properties": {
MEGA_LAYOUT2: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelCol: 4,
labelAlign: 'left'
},
properties: {
"shopIds": {
"type": "array:number",
"x-component": 'CardCheckBox',
"x-component-props": {
dataSource: [
{ logo: '', title: '会员', id: 1 },
{ logo: '', title: '小程序', id: 2 },
{ logo: '', title: 'H5', id: 3 },
{ logo: '', title: '渠道', id: 4 },
]
},
"title": "适用商城",
required: true,
}
}
}
}
},
"tab-3": {
type: 'object',
"x-component": 'tabpane',
"x-component-props": {
"tab": "适用会员"
},
properties: {
MEGA_LAYOUT3: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
labelCol: 4,
labelAlign: 'left'
},
properties: {
"isAllMemberShare": {
"type": "radio",
enum: [
{ label: '所有会员共享(默认)', value: 1 },
{ label: '指定会员', value: 0 },
],
"title": "选择渠道会员",
default: 1,
required: true,
},
applyMember: {
type: 'array:number',
"x-component": 'MultTable',
"x-component-props": {
columns: "{{tableColumns}}"
},
default: [
{ id: 1, name: '名称', type: '类型' },
{ id: 2, name: '名称1', type: '类型1' }
]
}
}
}
}
}
}
}
}
}
...@@ -112,6 +112,20 @@ export function omit(obj: any, arr: string[]) { ...@@ -112,6 +112,20 @@ export function omit(obj: any, arr: string[]) {
return tempObj return tempObj
} }
export const findItemAndDelete = (arr: any[], target) => {
const newArr = [...arr]
if (newArr.length > 0 && isObject(newArr[0])) {
return newArr.filter(v => v.id !== target)
}
const targetIndex = arr.indexOf(target)
if (targetIndex === -1) {
return newArr
} else {
newArr.splice(targetIndex, 1)
return newArr
}
}
export default { export default {
isArray, isArray,
isObject, isObject,
......
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