Commit 9fd09921 authored by 前端-李俊鑫's avatar 前端-李俊鑫

feat: 新增规则引擎配置

parent a6aae822
...@@ -202,7 +202,7 @@ const AuthConfigRoute: RouterChild = { ...@@ -202,7 +202,7 @@ const AuthConfigRoute: RouterChild = {
/** 请购单流程规则配置列表 */ /** 请购单流程规则配置列表 */
path: '/memberCenter/systemSetting/processManagement/buyingRequisitionProcess', path: '/memberCenter/systemSetting/processManagement/buyingRequisitionProcess',
name: '请购单流程规则配置', name: '请购单流程规则配置',
component: '@/pages/systemSetting/processEng/buyingRequisitionProcess' component: '@/pages/systemSetting/processEng/buyingRequisitionProcess',
}, },
{ {
/** 查看请购单流程规则配置 */ /** 查看请购单流程规则配置 */
...@@ -241,6 +241,7 @@ const AuthConfigRoute: RouterChild = { ...@@ -241,6 +241,7 @@ const AuthConfigRoute: RouterChild = {
name: '规则引擎配置', name: '规则引擎配置',
component: '@/pages/systemSetting/ruleEng/ruleEngConfig', component: '@/pages/systemSetting/ruleEng/ruleEngConfig',
hideInMenu: true, hideInMenu: true,
noMargin: true,
}, },
{ {
/** 请购单管理规则引擎 */ /** 请购单管理规则引擎 */
......
import React, { useState, useEffect } from 'react'
import { Select, SelectProps } from 'antd'
export interface PropsType<VT> extends SelectProps<VT> {
requestApi: Function
params?: Object
labelKey?: string
valueKey?: string
}
const FetchSelect = (props: PropsType<number>) => {
const {
requestApi,
params = {},
labelKey = 'name',
valueKey = 'id',
...rest
} = props
const [options, setOptions] = useState<any[]>([])
// 请求数据
const getOptionsData = async () => {
if (requestApi) {
const res = await requestApi(params)
if (res.code === 1000) {
const data = res.data?.data || res.data
const newOptions: any[] = data?.map((item) => {
return {
label: item[labelKey],
value: item[valueKey],
}
})
setOptions(newOptions)
}
}
}
useEffect(() => {
getOptionsData()
}, [])
return (
<Select
options={options}
placeholder='请选择'
{...rest}
/>
)
}
export default FetchSelect
...@@ -494,4 +494,25 @@ a { ...@@ -494,4 +494,25 @@ a {
border-left: 2px solid @primary-color; border-left: 2px solid @primary-color;
} }
} }
} }
\ No newline at end of file
// 定制化单选框样式
.use-radio-button {
.ant-radio-wrapper {
padding: 6px 16px;
border-radius: 4px;
border: 1px solid #F5F6F7;
background-color: #F5F6F7;
margin-right: 16px;
}
.ant-radio-wrapper-checked {
border: 1px solid #00A98F;
background-color: rgba(0, 169, 143, 0.04);
span {
color: #00A98F;
}
}
.ant-space {
width: 100%;
}
}
...@@ -30,7 +30,7 @@ const BuyingRequisitionProcess: React.FC = () => { ...@@ -30,7 +30,7 @@ const BuyingRequisitionProcess: React.FC = () => {
<Button <Button
type='primary' type='primary'
icon={<PlusOutlined/>} icon={<PlusOutlined/>}
onClick={() => history.push(`/memberCenter/systemSetting/processEng/buyingRequisitionProcess/add`)} onClick={() => history.push(`/memberCenter/systemSetting/processManagement/buyingRequisitionProcess/add`)}
> >
新增 新增
</Button> </Button>
...@@ -50,8 +50,8 @@ const BuyingRequisitionProcess: React.FC = () => { ...@@ -50,8 +50,8 @@ const BuyingRequisitionProcess: React.FC = () => {
'删除': true, '删除': true,
} }
const operationHandler = { const operationHandler = {
'修改': () => { history.push(`/memberCenter/systemSetting/processEng/buyingRequisitionProcess/edit?id=${record.id}`) }, '修改': () => { history.push(`/memberCenter/systemSetting/processManagement/buyingRequisitionProcess/edit?id=${record.id}`) },
'查看': () => { history.push(`/memberCenter/systemSetting/processEng/buyingRequisitionProcess/detail?id=${record.id}`) }, '查看': () => { history.push(`/memberCenter/systemSetting/processManagement/buyingRequisitionProcess/detail?id=${record.id}`) },
'删除': () => {} '删除': () => {}
} }
return ( return (
...@@ -88,7 +88,7 @@ const BuyingRequisitionProcess: React.FC = () => { ...@@ -88,7 +88,7 @@ const BuyingRequisitionProcess: React.FC = () => {
width: 160, width: 160,
ellipsis: true, ellipsis: true,
render: (text: unknown, record: any) => ( render: (text: unknown, record: any) => (
<EyePreview url={`/memberCenter/systemSetting/processEng/buyingRequisitionProcess/detail?id=${record.id}`}>{text}</EyePreview> <EyePreview url={`/memberCenter/systemSetting/processManagement/buyingRequisitionProcess/detail?id=${record.id}`}>{text}</EyePreview>
) )
}, },
{ title: '流程名称', dataIndex: 'processName', key: 'processName' }, { title: '流程名称', dataIndex: 'processName', key: 'processName' },
......
import React, { useRef, useState, useCallback, forwardRef, memo } from 'react'
import { Form } from 'antd'
import StandardTable from '@/components/StandardTable'
import { ColumnType } from 'antd/lib/table'
import NiceForm from '@/components/NiceForm'
import { createFormActions } from '@formily/antd'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { schema } from './schema'
import CommonDrawer from '../CommonDrawer'
import { getOrderDeliveryNoticeOrderVendorPage } from '@/services/OrderNewV2Api'
interface PropsType {
onOk?: () => void
}
const ConfigDrawer = (props: PropsType, ref) => {
const [form] = Form.useForm()
const formActions = createFormActions()
const { onOk } = props
const tableRef = useRef<any>({})
const handleOk = useCallback(() => {
form.validateFields().then((values) => {
onOk?.()
})
}, [])
const handleShow = useCallback((params: Object) => {
}, [])
const fetchData = (params: any) => {
return new Promise((resolve) => {
getOrderDeliveryNoticeOrderVendorPage(params).then(({ code, data }) => {
if (code === 1000) {
resolve(data)
}
})
})
}
const columns: ColumnType<any>[] = [
{
title: '通知单号',
dataIndex: 'noticeNo',
key: 'noticeNo',
width: 160,
},
{ title: '通知单摘要', dataIndex: 'digest', key: 'digest' },
{ title: '送货日期', dataIndex: 'deliveryTime', key: 'deliveryTime' },
{ title: '采购会员', dataIndex: 'memberName', key: 'memberName' },
{ title: '单据时间', dataIndex: 'createTime', key: 'createTime' },
]
return (
<CommonDrawer
ref={ref}
title='编辑'
width={400}
onOk={handleOk}
onShow={handleShow}
>
<StandardTable
currentRef={tableRef}
columns={columns}
tableProps={{ rowKey: 'id', }}
fetchTableData={(params: unknown) => fetchData(params)}
controlRender={
<NiceForm
actions={formActions}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'noticeNo',
FORM_FILTER_PATH,
)
}}
schema={schema}
/>
}
/>
</CommonDrawer>
)
}
export default memo(forwardRef(ConfigDrawer))
import { ISchema } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
export const schema: ISchema = {
type: 'object',
properties: {
mageLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
className: 'useMegaStart'
},
properties: {
noticeNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
allowClear: true,
placeholder: '请输入通知单号查询'
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start'
},
colStyle: {
marginRight: 20,
},
},
properties: {
digest: {
type: 'string',
'x-component-props': {
allowClear: true,
placeholder: '通知单摘要'
}
},
'[startDate, endDate]': {
type: 'daterange',
'x-component-props': {
allowClear: true,
placeholder: ['送货开始日期', '送货结束日期'],
},
},
memberName: {
type: 'string',
'x-component-props': {
allowClear: true,
placeholder: '采购会员'
}
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
}
}
}
}
}
}
.common-drawer {
:global {
.ant-drawer-header-title {
flex-direction: row-reverse;
.ant-drawer-close {
margin-right: 0;
}
}
.ant-drawer-body {
padding: 16px;
}
.ant-drawer-footer {
border-top: 0;
}
}
}
import React, { useState, useImperativeHandle, forwardRef, memo } from 'react'
import { Drawer, Space, Button, DrawerProps } from 'antd'
import styles from './index.less'
export type HandleType = {
show: (flag?: boolean, params?: Object) => void;
}
interface PropsType extends DrawerProps {
onOk?: () => void
okText?: string
onCancel?: () => void
cancelText?: string
children?: React.ReactNode
onShow?: (params: Object) => void
specialFooter?: React.ReactNode
}
const CommonDrawer = (props: PropsType, ref: any) => {
const { onOk, onCancel, onShow, okText = '确定', cancelText = '取消', specialFooter, children, ...rest } = props
const [visible, setVisible] = useState<boolean>(false)
const _onCancel = () => {
setVisible(false)
onCancel?.()
}
useImperativeHandle(ref, () => ({
show(flag = true, params = {}) {
setVisible(flag)
onShow?.(params)
}
}))
return (
<Drawer
className={styles['common-drawer']}
visible={visible}
onClose={_onCancel}
footer={
<div>
<div>{specialFooter}</div>
<div style={{ textAlign: 'right' }}>
<Space size={12} >
{ onCancel && <Button onClick={_onCancel}>{cancelText}</Button> }
{ onOk && <Button type="primary" onClick={onOk}>{okText}</Button> }
</Space>
</div>
</div>
}
{...rest}
>
{children}
</Drawer>
)
}
export default memo(forwardRef(CommonDrawer))
import React, { useState, forwardRef, memo, useCallback } from 'react'
import { Form } from 'antd'
import CommonDrawer from '../CommonDrawer'
import ProcessRules from '../ProcessRules'
interface PropsType {
onChange?: () => void
}
const ConfigDrawer = (props: PropsType, ref) => {
const [form] = Form.useForm()
const { onChange } = props
const handleOk = useCallback(() => {
form.validateFields().then((values) => {
onChange?.()
})
}, [])
const handleCancel = useCallback(() => {
onChange?.()
}, [])
const handleShow = useCallback((params: Object) => {
}, [])
return (
<CommonDrawer
ref={ref}
title='编辑'
width={400}
onOk={handleOk}
onCancel={handleCancel}
onShow={handleShow}
>
<ProcessRules form={form}/>
</CommonDrawer>
)
}
export default memo(forwardRef(ConfigDrawer))
.card {
margin-bottom: 16px;
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
.title {
font-size: 12px;
color: #91959B;
}
.icon {
width: 16px;
height: 16px;
cursor: pointer;
}
}
:global {
.ant-form-item {
margin-bottom: 16px;
}
}
}
/**
* 流程规则组件
* @author: Crayon
*/
import React, { useEffect, useState, useRef } from 'react'
import { Button, Form, Input, Radio, Checkbox, FormInstance, Row, Col, Space } from 'antd'
import { validatorByte } from '@/utils/regExp'
import { DeleteOutlined } from '@ant-design/icons'
import styles from './index.less'
type PropsType = {
title?: string | React.ReactNode
onClick?: () => void
children?: React.ReactNode
}
const rules = [{ required: true }];
const ConfigFieldCard: React.FC<PropsType> = ({ title, onClick, children }) => {
return (
<div className={styles['card']}>
<div className={styles['header']}>
<div className={styles['title']}>{title}</div>
{
onClick ? (
<div
className={styles['icon']}
onClick={onClick}
title='删除'
>
<DeleteOutlined/>
</div>
)
:
<div></div>
}
</div>
<div className={styles['body']}>{children}</div>
</div>
)
}
export default ConfigFieldCard
@bg-color: #c8cacd;
@theme-color: #00a98f;
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.common-style {
.flex-center;
font-size: 14px;
background-color: #fff;
border: 2px solid #c8cacd;
z-index: 2;
}
.config-box {
min-height: 100px;
.flex-center;
flex-direction: column;
.item-box {
.flex-center;
flex-direction: column;
.start {
width: 88px;
height: 88px;
border-radius: 50%;
.common-style;
}
.step {
width: 228px;
height: 64px;
border-radius: 8px;
.common-style;
cursor: pointer;
&:hover {
border-color: @theme-color;
}
}
.end {
.start;
}
.active {
border-color: @theme-color;
}
.arrow {
height: 48px;
width: 2px;
background-color: @bg-color;
position: relative;
&::before {
display: block;
content: '';
position: relative;
left: -4px;
top: -4px;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: @bg-color;
}
&::after {
display: block;
content: '';
position: relative;
left: -4px;
bottom: -28px;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 10px solid @bg-color;
}
}
}
}
import React, { forwardRef, useImperativeHandle, useState, memo } from 'react'
import cs from 'classnames'
import styles from './index.less'
export type FlowChartOptionsType = {
label: string,
value: string | number
}
export type RefHandleType = {
setActive: (value: string | number) => void
}
type PropsType = {
children?: React.ReactNode
options?: FlowChartOptionsType[]
onChange?: (value: string | number) => void
}
type ItemPropsType = {
type?: 'start' | 'step' | 'end'
children?: React.ReactNode
onClick?: (value?: string | number) => void
active?: boolean
value?: string | number
}
const FlowChart = ({ children, options, onChange }: PropsType, ref) => {
const [activeValue, setActiveValue] = useState<string | number>()
const onItemChange = (value: string | number) => {
setActiveValue(value)
onChange?.(value)
}
useImperativeHandle(ref, () => ({
setActive: (value: string | number) => {
setActiveValue(value)
}
}))
return (
<div className={styles['config-box']}>
<FlowChartItem type='start'>开始</FlowChartItem>
{
options ?
options.map(item => (
<FlowChartItem
key={item.value}
active={item.value === activeValue}
onClick={() => { onItemChange(item.value) }}
>
{item.label}
</FlowChartItem>
))
:
children && React.Children.map(children, (child: any) => {
return React.cloneElement(child, {
active: child.props.value === activeValue,
onClick: (value) => { onItemChange(value) }
});
})
}
<FlowChartItem type='end'>结束</FlowChartItem>
</div>
)
}
const FlowChartItem = ({ children, type = 'step', active, onClick, value }: ItemPropsType) => {
return (
<div className={styles['item-box']}>
<div
className={cs(styles[type], active && styles['active'])}
onClick={() => onClick(value)}
>
{children}
</div>
{type !== 'end' && <div className={styles['arrow']}></div>}
</div>
)
}
const MemoRefFlowChart = memo(forwardRef(FlowChart))
// @ts-ignore
MemoRefFlowChart.Item = FlowChartItem
export default MemoRefFlowChart as React.MemoExoticComponent<React.ForwardRefExoticComponent<PropsType & React.RefAttributes<unknown>>> & { Item: typeof FlowChartItem }
import React, { useRef, useState, useCallback, forwardRef, memo, useImperativeHandle } from 'react'
import { Form } from 'antd'
import StandardTable from '@/components/StandardTable'
import { ColumnType } from 'antd/lib/table'
import NiceForm from '@/components/NiceForm'
import { createFormActions } from '@formily/antd'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { schema } from './schema'
import CommonDrawer, { HandleType } from '../CommonDrawer'
import { getOrderDeliveryNoticeOrderVendorPage } from '@/services/OrderNewV2Api'
export type RefHandleType = {
show: (flag?: boolean, params?: Object) => void
setRows: (rows: any[]) => void;
}
interface PropsType {
onOk?: (rows: any[], rowKeys: any[]) => void
}
const MaterialDrawer = (props: PropsType, ref) => {
const formActions = createFormActions()
const { onOk } = props
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([])
const [selectedRows, setSelectedRows] = useState<any>([])
const tableRef = useRef<any>({})
const drawRef = useRef<HandleType>()
const handleOk = useCallback(() => {
onOk?.(selectedRows, selectedRowKeys)
}, [selectedRows, selectedRowKeys])
const handleShow = useCallback((params: Object) => {
}, [])
const fetchData = (params: any) => {
return new Promise((resolve) => {
getOrderDeliveryNoticeOrderVendorPage(params).then(({ code, data }) => {
if (code === 1000) {
resolve(data)
}
})
})
}
const handleSelectChange = (record, selected, selectedRow, nativeEvent) => {
let childArr = [...selectedRowKeys];
let childRowArr = [...selectedRows]
if (selected) {
childArr.push(record.id);
childRowArr.push(record);
} else {
childArr.splice(
childArr.findIndex((item) => item === record.id),
1
);
childRowArr.splice(
childRowArr.findIndex((item) => item.id === record.id),
1
);
}
setSelectedRowKeys(childArr)
setSelectedRows(childRowArr)
};
const handleSelectAll = (selected, selectedRow, changeRows) => {
let childArr = [...selectedRowKeys];
let childRowArr = [...selectedRows];
if (selected) {
childArr = Array.from(
new Set([...childArr, ...changeRows.map((item) => item.id)])
);
childRowArr = Array.from(
new Set([...childRowArr, ...changeRows])
);
} else {
childArr = childArr.filter(
(item) => !changeRows.some((e) => e.id === item)
);
childRowArr = childRowArr.filter(
(item) => !changeRows.some((e) => e.id === item.id)
);
}
setSelectedRowKeys(childArr);
setSelectedRows(childRowArr);
}
useImperativeHandle(ref, () => ({
show(flag = true, params = {}) {
drawRef?.current?.show(flag, params)
},
setRows(rows: any[]) {
const rowKeys = rows.map(item => item.id)
setSelectedRows(rows)
setSelectedRowKeys(rowKeys)
}
}))
const columns: ColumnType<any>[] = [
{
title: '通知单号',
dataIndex: 'noticeNo',
key: 'noticeNo',
width: 160,
},
{ title: '通知单摘要', dataIndex: 'digest', key: 'digest' },
{ title: '送货日期', dataIndex: 'deliveryTime', key: 'deliveryTime' },
{ title: '采购会员', dataIndex: 'memberName', key: 'memberName' },
{ title: '单据时间', dataIndex: 'createTime', key: 'createTime' },
]
return (
<CommonDrawer
ref={drawRef}
title='选择物料'
width={1000}
onOk={handleOk}
onShow={handleShow}
onCancel={() => { }}
>
<StandardTable
currentRef={tableRef}
columns={columns}
tableProps={{ rowKey: 'id', }}
fetchTableData={(params: unknown) => fetchData(params)}
rowSelection={{
selectedRowKeys: selectedRowKeys,
onSelect: handleSelectChange,
onSelectAll: handleSelectAll,
}}
controlRender={
<NiceForm
actions={formActions}
onSubmit={values => tableRef.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'noticeNo',
FORM_FILTER_PATH,
)
}}
schema={schema}
/>
}
/>
</CommonDrawer>
)
}
export default memo(forwardRef(MaterialDrawer))
import { ISchema } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
export const schema: ISchema = {
type: 'object',
properties: {
mageLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
className: 'useMegaStart'
},
properties: {
noticeNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
allowClear: true,
placeholder: '请输入通知单号查询'
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
justifyContent: 'flex-start'
},
colStyle: {
marginRight: 20,
},
},
properties: {
digest: {
type: 'string',
'x-component-props': {
allowClear: true,
placeholder: '通知单摘要'
}
},
'[startDate, endDate]': {
type: 'daterange',
'x-component-props': {
allowClear: true,
placeholder: ['送货开始日期', '送货结束日期'],
},
},
memberName: {
type: 'string',
'x-component-props': {
allowClear: true,
placeholder: '采购会员'
}
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
}
}
}
}
}
}
.rules {
padding-bottom: 16px;
.rules-item {
margin-bottom: 24px;
}
.rules-item-hidden {
height: 32px;
overflow: hidden;
}
.rule-wrap {
display: flex;
align-items: center;
width: 368px;
height: 32px;
margin-bottom: 16px;
padding: 0 4px;
border-radius: 4px;
color: #252D37;
font-size: 14px;
background-color: #F5F6F7;
cursor: pointer;
&:hover {
border: 1px solid #00A98F;
}
:global {
.anticon {
padding: 0 4px;
}
}
}
.fields {
:global {
.ant-form-item {
margin-bottom: 16px;
}
}
}
.add {
position: absolute;
bottom: 50px;
left: 0;
height: 42px;
width: 100%;
padding-left: 16px;
padding-top: 10px;
border-top: 1px solid #F5F6F7;
background-color: #FFF;
}
}
/**
* 流程规则组件
* @author: Crayon
*/
import React, { useEffect, useState, useRef } from 'react'
import { Button, Form, Input, Radio, Checkbox, FormInstance, Row, Col, Space, Select, DatePicker } from 'antd'
import { validatorByte } from '@/utils/regExp'
import { CaretDownFilled, CaretRightFilled, PlusOutlined } from '@ant-design/icons'
import ConfigFieldCard from '../ConfigFieldCard'
import cs from 'classnames'
import styles from './index.less'
import SelectMaterial from '../SelectMaterial'
import SelectRoles from '../SelectRoles'
type PropsType = {
form?: FormInstance
}
const rules = [{ required: true }];
const mockFieldType = [
{ label: '物料编号', value: 1 },
{ label: '品类', value: 2 },
{ label: '目录价', value: 3 },
{ label: '创建日期', value: 4 },
]
const mockFieldCondition = [
{ label: '是', value: 1 },
{ label: '不是', value: 2 },
{ label: '包含', value: 3 },
{ label: '不包含', value: 4 },
]
const interrelationOptions = [
{ label: '并且', value: 1 },
{ label: '或者', value: 2 },
]
const ProcessRules: React.FC<PropsType> = ({ form }) => {
const [ruleShowConfig, setRuleShowConfig] = useState<Object>({})
const onFinish = values => {
console.log("Received values of form:", values);
};
const onRuleWrap = (key: string) => {
const newConfig = { ...ruleShowConfig }
newConfig[key] = !(!!newConfig[key])
setRuleShowConfig(newConfig)
}
console.log('1', 1)
return (
<Form
form={form}
onFinish={onFinish}
onFieldsChange={(_, _all) => {
console.log('form.getFieldsValue()', form.getFieldsValue())
}}
>
<Form.List name="rulesList">
{(ruleFields, { add: ruleAdd, remove: ruleRemove }) => {
return (
<div className={styles['rules']}>
{ruleFields.map((ruleField: any, ruleIndex) => (
<div
className={cs(styles['rules-item'], !ruleShowConfig[ruleField.key] && styles['rules-item-hidden'])}
key={ruleField.key}
>
<div
className={styles['rule-wrap']}
onClick={() => onRuleWrap(ruleField.key)}
>
<CaretRightFilled rotate={ruleShowConfig[ruleField.key] ? 90 : 0} style={{ fontSize: 12 }} />
{`流程规则 ${ruleIndex + 1}`}
</div>
<Form.List
name={[ruleField.name, "fieldsList"]}
>
{(fields, { add: fieldAdd, remove: fieldRemove }) => {
return (
<div className={styles['fields']}>
{fields.map((field: any, index) => (
<div key={field.key}>
<ConfigFieldCard
title={`条件 ${index + 1}`}
onClick={() => { fieldRemove(index) }}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name={[field.name, "fieldType"]}
fieldKey={[field.fieldKey, "fieldType"]}
>
<Select options={mockFieldType} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name={[field.name, "fieldCondition"]}
fieldKey={[field.fieldKey, "fieldCondition"]}
>
<Select options={mockFieldCondition} />
</Form.Item>
</Col>
</Row>
<Form.Item
name={[field.name, "fieldValue"]}
fieldKey={[field.fieldKey, "fieldValue"]}
>
{/* <Input placeholder="请输入" /> */}
{/* <DatePicker style={{ width: '100%' }} placeholder="请选择" /> */}
<SelectMaterial />
</Form.Item>
</ConfigFieldCard>
</div>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
fieldAdd({
fieldType: mockFieldType[0].value,
fieldCondition: mockFieldCondition[0].value,
})
}}
style={{ width: "100%" }}
>
<PlusOutlined /> 新增字段
</Button>
</Form.Item>
</div>
)
}}
</Form.List>
<ConfigFieldCard title='相互关系'>
<Form.Item
name={[ruleField.name, "interrelation"]}
fieldKey={[ruleField.fieldKey, "interrelation"]}
>
<Radio.Group className='use-radio-button'>
{interrelationOptions.map(_item => (
<Radio key={_item.value} value={_item.value}>{_item.label}</Radio>
))}
</Radio.Group>
</Form.Item>
</ConfigFieldCard>
<ConfigFieldCard title='处理角色'>
<Form.Item
name={[ruleField.name, "dealRole"]}
fieldKey={[ruleField.fieldKey, "dealRole"]}
>
<SelectRoles />
{/* <Select options={mockFieldCondition} /> */}
</Form.Item>
</ConfigFieldCard>
</div>
))}
<div className={styles['add']}>
<Form.Item>
<Button
type="primary"
onClick={() => {
ruleAdd({
interrelation: interrelationOptions[0].value,
dealRole: 48
})
}}>
添加规则
</Button>
</Form.Item>
</div>
</div>
)
}}
</Form.List>
</Form>
)
}
export default ProcessRules
import React, { useRef, useState, useCallback, forwardRef, memo, useImperativeHandle } from 'react'
import StandardTable from '@/components/StandardTable'
import { ColumnType } from 'antd/lib/table'
import CommonDrawer, { HandleType } from '../CommonDrawer'
import { getOrderDeliveryNoticeOrderVendorPage } from '@/services/OrderNewV2Api'
interface PropsType {
onOk?: (rows: any[], rowKeys: any[]) => void
}
const SeeUserDrawer = (props: PropsType, ref) => {
const fetchData = (params: any) => {
return new Promise((resolve) => {
getOrderDeliveryNoticeOrderVendorPage(params).then(({ code, data }) => {
if (code === 1000) {
resolve(data)
}
})
})
}
const columns: ColumnType<any>[] = [
{
title: '通知单号',
dataIndex: 'noticeNo',
key: 'noticeNo',
width: 160,
},
{ title: '通知单摘要', dataIndex: 'digest', key: 'digest' },
{ title: '送货日期', dataIndex: 'deliveryTime', key: 'deliveryTime' },
{ title: '采购会员', dataIndex: 'memberName', key: 'memberName' },
{ title: '单据时间', dataIndex: 'createTime', key: 'createTime' },
]
return (
<CommonDrawer
ref={ref}
title='用户列表'
width={1000}
footer={null}
>
<StandardTable
columns={columns}
tableProps={{ rowKey: 'id', }}
fetchTableData={(params: any) => fetchData(params)}
/>
</CommonDrawer>
)
}
export default memo(forwardRef(SeeUserDrawer))
import React, { useState, memo, useCallback, useRef, useEffect } from 'react'
import { HandleType } from '../CommonDrawer'
import MaterialDrawer, { RefHandleType } from '../MaterialDrawer'
import WrapSelect from '../WrapSelect'
interface PropsType {
onChange?: (data: any[]) => void
value?: any
}
const SelectMaterial = (props: PropsType) => {
const { onChange, value } = props
const [selectData, setSelectData] = useState<any[]>([])
const ref = useRef<RefHandleType>()
const handleOk = useCallback((rows: any[]) => {
onChange?.(rows)
setSelectData(rows)
ref?.current?.show(false)
}, [])
const onItemDelete = (id: string | number) => {
const newSelectData = selectData.filter(item => item.id !== id)
setSelectData(newSelectData)
ref?.current?.setRows(newSelectData)
}
useEffect(() => {
if (value) {
setSelectData(value)
}
}, [])
return (
<>
<WrapSelect
onIconClick={() => { ref?.current?.show() }}
onItemDelete={onItemDelete}
data={selectData}
labelKey='memberName'
/>
<MaterialDrawer
ref={ref}
onOk={handleOk}
/>
</>
)
}
export default memo(SelectMaterial)
import React, { useState, memo, useCallback, useRef, useEffect } from 'react'
import MaterialDrawer, { RefHandleType } from '../MaterialDrawer'
import WrapSelect from '../WrapSelect'
interface PropsType {
onChange?: (data: any[]) => void
value?: any
}
const SelectMaterial = (props: PropsType) => {
const { onChange, value } = props
const [selectData, setSelectData] = useState<any[]>([])
const ref = useRef<RefHandleType>()
const handleOk = useCallback((rows: any[]) => {
onChange?.(rows)
setSelectData(rows)
ref?.current?.show(false)
}, [])
const onItemDelete = (id: string | number) => {
const newSelectData = selectData.filter(item => item.id !== id)
setSelectData(newSelectData)
ref?.current?.setRows(newSelectData)
}
useEffect(() => {
if (value) {
setSelectData(value)
}
}, [])
return (
<>
<WrapSelect
onIconClick={() => { ref?.current?.show() }}
onItemDelete={onItemDelete}
data={selectData}
labelKey='memberName'
/>
<MaterialDrawer
ref={ref}
onOk={handleOk}
/>
</>
)
}
export default memo(SelectMaterial)
import React, { useState, memo, useRef } from 'react'
import { getOrderDeliveryNoticeOrderVendorPage } from '@/services/OrderNewV2Api'
import { Button, Col, Row } from 'antd'
import FetchSelect from '@/components/FetchSelect'
import { HandleType } from '../CommonDrawer'
import SeeUserDrawer from '../SeeUserDrawer'
const SelectRoles = (props: any) => {
const { onChange, ...rest } = props
const valueRef = useRef<any>()
const drawRef = useRef<HandleType>()
const _onChange = (value) => {
valueRef.current.ref = value
onChange?.(value)
}
return (
<>
<Row gutter={16}>
<Col style={{ flex: 1 }}>
<FetchSelect
style={{ width: '100%' }}
labelKey='memberName'
valueKey='id'
requestApi={getOrderDeliveryNoticeOrderVendorPage}
onChange={_onChange}
{...rest}
/>
</Col>
<Col>
<Button
style={{ marginRight: 0 }}
onClick={() => { drawRef?.current?.show() }}
>
查看用户
</Button>
</Col>
</Row>
<SeeUserDrawer ref={drawRef}/>
</>
)
}
export default memo(SelectRoles)
.wrap-select {
display: flex;
align-items: center;
width: 100%;
}
.content-box {
position: relative;
display: flex;
flex-wrap: wrap;
flex: 1;
min-height: 32px;
padding: 4px 36px 0 4px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
background-color: #F5F6F7;
}
.content-item {
display: flex;
align-items: center;
height: 24px;
padding: 4px 8px;
margin-right: 4px;
margin-bottom: 4px;
border: 1px solid #FFF;
background-color: #FFF;
border-radius: 4px;
font-size: 12px;
color: #5C626A;
cursor: pointer;
&:hover {
border-color: #00A98F;
}
}
.icon-box {
position: absolute;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 100%;
min-height: 32px;
border-radius: 4px;
background-color: #00A98F;
cursor: pointer;
}
.content-placeholder {
padding-left: 4px;
padding-top: 2px;
font-size: 12px;
color: #C8CACD;
}
import React, { useState, forwardRef, memo, useCallback } from 'react'
import { Form, Space } from 'antd'
import styles from './index.less'
import { LinkOutlined, CloseOutlined } from '@ant-design/icons'
interface PropsType {
onIconClick?: () => void
onItemClick?: (a: any) => void
onItemDelete?: (a: any) => void
data?: any[]
labelKey?: string
valueKey?: string
}
const WrapSelect = (props: PropsType) => {
const { onIconClick, onItemClick, onItemDelete, data = [], labelKey = 'name', valueKey='id' } = props
return (
<div className={styles['wrap-select']}>
<div className={styles['content-box']}>
{
!!data.length ?
<>
{
data.map((item, index) => (
index < 3 &&
<div
key={item[valueKey]}
className={styles['content-item']}
onClick={() => onItemClick?.(item[valueKey])}
>
{item[labelKey]}
<CloseOutlined
style={{ fontSize: 12, marginLeft: 8 }}
onClick={() => onItemDelete?.(item[valueKey])}
/>
</div>
))
}
{
data.length > 3 && (
<div className={styles['content-item']} onClick={() => onIconClick?.()}>
更多
</div>
)
}
</>
:
<div className={styles['content-placeholder']}>请选择</div>
}
<div className={styles['icon-box']} onClick={() => onIconClick?.()}>
<LinkOutlined style={{ fontSize: 16, color: '#FFF' }} />
</div>
</div>
</div>
)
}
export default memo(WrapSelect)
...@@ -2,12 +2,52 @@ ...@@ -2,12 +2,52 @@
* 系统能力 - 规则引擎 - 规则引擎配置 * 系统能力 - 规则引擎 - 规则引擎配置
* @author: Crayon * @author: Crayon
*/ */
import React from 'react' import React, { useEffect, useRef, useCallback } from 'react'
import AnchorPage from '@/components/AnchorPage'
import { history } from 'umi'
import usePrompt from '@/hooks/usePrompt'
import FlowChart, { FlowChartOptionsType, RefHandleType } from './components/FlowChart'
import ConfigDrawer from './components/ConfigDrawer'
import { HandleType } from './components/CommonDrawer'
const RuleEngConfig: React.FC = () => { const RuleEngConfig: React.FC = () => {
const flowRef = useRef<RefHandleType>()
const drawRef = useRef<HandleType>()
const options: FlowChartOptionsType[] = [
{ label: '提交审核', value: 1 },
{ label: '审核 (一级)', value: 2 },
{ label: '审核 (二级)', value: 3 },
]
const handleDrawer = useCallback(() => {
flowRef?.current?.setActive('')
}, [])
const onFlowChartChange = useCallback((value: string | number) => {
drawRef?.current?.show(true, { id: value })
}, [])
useEffect(() => {
}, [])
return ( return (
<div>RuleEngConfig</div> <AnchorPage
title='规则引擎配置'
onBack={() => history.goBack()}
anchors={[]}
>
<FlowChart
ref={flowRef}
options={options}
onChange={onFlowChartChange}
/>
<ConfigDrawer
ref={drawRef}
onChange={handleDrawer}
/>
</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