Commit c3a8b780 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat: 请款单规则配置接口接入

parent 094f8221
......@@ -52,6 +52,18 @@ const router = {
},
{
path: '/system/ruleSettingManager/invoiceProcessEng/edit',
name: '编辑请款单流程规则',
hideInMenu: true,
component: '@/pages/systemManage/invoiceProcessEng/add',
},
{
path: '/system/ruleSettingManager/invoiceProcessEng/preview',
name: '请款单流程规则详情',
hideInMenu: true,
component: '@/pages/systemManage/invoiceProcessEng/add',
},
{
path: '/system/ruleSettingManager/payStrategyList',
name: '会员支付策略配置',
noMargin: true,
......
......@@ -18,6 +18,8 @@
font-size: 16px;
font-weight: 500;
margin-left: 8px;
display: flex;
align-items: center;
}
}
}
......
import React, { Fragment, useState } from 'react';
import React, { Fragment, useEffect, useState } from 'react';
import { history } from 'umi';
import PeripheralLayout from '@/components/DetailLayout';
import { Button, Form } from 'antd';
import { Button, Form, message } from 'antd';
import { SaveOutlined } from '@ant-design/icons';
import ProcessEngLayout from './components/processEng';
import ProcessSelectLayout from './components/processSelect';
import InvoiceTypeLayout from './components/invoiceType';
import useFields from './useFields';
import { getSettleAccountsBusinessApplyAmountProcessGet, postSettleAccountsBusinessApplyAmountProcessSave, postSettleAccountsBusinessApplyAmountProcessStatusUpdate } from '@/services/SettleV2Api';
export const layout: any = {
colon: false,
......@@ -12,44 +15,129 @@ export const layout: any = {
labelAlign: "left"
};
const progress = {
display: 'flex',
alignItems: 'center',
width: '240px',
height: '16px',
marginLeft: '8px',
padding: '0 8px',
borderRadius: '8px',
fontSize: '12px',
fontWeight: 'normal',
}
const COLOR = {
error: { bg: '#FDE8EA', text: '#E34D59' },
warning: { bg: '#FCF7E8', text: '#D8A042' },
success: { bg: '#E4F7EF', text: '#00A98F' },
}
const AddInvoiceProcessEng: React.FC<{}> = () => {
const [form] = Form.useForm();
const [percent, setPercent] = useState<number>(0);
/**计算输入框输入了百分之多少 */
const onValuesChange = (allValues) => {
const values = Object.values(allValues);
let num = 0;
values.forEach(_item => {
if (_item) {
num += 1
const [form] = Form.useForm();
const { percent, onFieldsChange } = useFields();
const { query: { processId }, pathname } = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const [loading, setLoading] = useState<boolean>(false);
const getColor = (scale) => {
if (scale < 60) {
return COLOR.error
}
})
console.log(((num/values.length) * 100).toFixed(0) + '%')
console.log(form.getFieldsValue())
}
if (scale < 85) {
return COLOR.warning
}
if (scale <= 100) {
return COLOR.success
}
}
useEffect(() => {
onFieldsChange(form)
}, [])
const handleSubmit = () => {
let fetchApi = (path === 'edit' ? postSettleAccountsBusinessApplyAmountProcessStatusUpdate : postSettleAccountsBusinessApplyAmountProcessSave)
form.validateFields().then(values => {
setLoading(true)
const params = {
...values,
allMembers: values.allMembers === 1 ? true : false,
members: values.members.map(_item => {
return {
memberId: _item.memberId,
roleId: _item.roleId,
}
})
}
delete values.allMembers;
delete values.members;
path === 'edit' && (params.processId = processId)
fetchApi({ ...params }).then(res => {
if (res.code !== 1000) {
setLoading(false)
return
}
history.goBack()
})
})
}
useEffect(() => {
if (processId) {
getSettleAccountsBusinessApplyAmountProcessGet({ processId: processId.toString() }).then(res => {
if (res.code !== 1000) {
message.error(res.message)
return
}
const { data } = res
console.log(data, 'data')
form.setFieldsValue({
'name': data.name,
'baseProcessId': data.baseProcessId,
'allMembers': data.allMembers ? 1 : 2,
'members': data.allMembers
})
onFieldsChange(form)
})
}
}, [])
return (
<Fragment>
<PeripheralLayout
hideBreak
detail='新增请款单流程规则'
no={
<div
style={{ ...progress, backgroundColor: getColor(percent).bg, color: getColor(percent).text }}
>
信息完整度 {percent.toFixed(0)}%
</div>
}
tabLink={[
{ title: '流程规则', id: 'processEng' },
{ title: '流程选择', id: 'processSelect' },
{ title: '适用会员', id: 'invoiceType' },
]}
effect={
<Button
icon={<SaveOutlined />}
type="primary"
>
保存
</Button>
path !== 'preview' && (
<Button
icon={<SaveOutlined />}
type="primary"
loading={loading}
onClick={() => handleSubmit()}
>
保存
</Button>
)
}
components={
<Form form={form} {...layout} onValuesChange={(_, allValues) => onValuesChange(allValues) }>
<ProcessEngLayout />
<ProcessSelectLayout />
<InvoiceTypeLayout />
<Form form={form} {...layout} onFieldsChange={() => onFieldsChange(form)}>
<ProcessEngLayout disabled={path === 'preview'} />
<ProcessSelectLayout disabled={path === 'preview'} onFieldsChange={onFieldsChange} form={form} />
<InvoiceTypeLayout disabled={path === 'preview'} onFieldsChange={onFieldsChange} form={form} processId={processId} />
</Form>
}
/>
......
......@@ -3,8 +3,8 @@ import { ColumnType } from 'antd/lib/table/interface';
/** 流程规则ID */
export const id: ColumnType<any> = {
title: '流程规则ID',
key: 'id',
dataIndex: 'id',
key: 'processId',
dataIndex: 'processId',
}
/** 流程规则名称 */
......
import React, { useCallback, useState } from 'react';
import { Button, Form, Radio, Space, Table } from 'antd';
import { FormInstance } from 'antd/es/form/Form';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Form, message, Popconfirm, Radio, Space, Table } from 'antd';
import { FormInstance } from 'antd/es/form/hooks/useForm';
import { ColumnType } from 'antd/lib/table/interface';
import { PlusOutlined } from '@ant-design/icons';
import CardLayout from '../card';
import styles from './index.less';
import { operation } from '../../columns';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import TableModal from '@/components/TableModal';
import { getMemberManageAllProviderPage } from '@/services/MemberV2Api';
import CardLayout from '../card';
import styles from './index.less';
import { operation } from '../../columns';
import useFields from '../../useFields';
import { getSettleAccountsBusinessApplyAmountProcessMemberPage } from '@/services/SettleV2Api';
interface InvoiceTypeProps {
/** FormInstance */
form?: FormInstance,
onFieldsChange?: (values: any) => void,
disabled?: boolean,
processId: string
}
const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
const { form } = props;
const { form, onFieldsChange, disabled, processId } = props;
const [visible, setVisible] = useState<boolean>(false);
const [member, setMember] = useState<any>({})
const [member, setMember] = useState<any>([])
const mock = [
{ value: 1, label: '所有会员(默认)' },
{ value: 2, label: '指定会员' },
......@@ -28,8 +33,8 @@ const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
const columns: ColumnType<any>[] = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
dataIndex: 'memberId',
key: 'memberId',
},
{
title: '会员名称',
......@@ -71,10 +76,52 @@ const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
}
const handleConfirm = (selectRow: number[] | string[], selectedRows: { [key: string]: any }[]) => {
console.log(selectRow, 'selectRow');
console.log(selectedRows, 'selectedRows');
setMember(selectedRows)
form.setFieldsValue({
'members': selectedRows
})
onFieldsChange(form)
toggle(false)
}
const confirm = (records) => {
const params = member.filter(_item => _item.id !== records.id);
console.log(params)
setMember([...params])
}
useEffect(() => {
if (processId) {
getSettleAccountsBusinessApplyAmountProcessMemberPage({ processId } as any).then(res => {
if (res.code !== 1000) {
message.error(res.message);
return
}
setMember(res.data);
form.setFieldsValue({ 'members': res.data })
onFieldsChange(form)
})
}
}, [processId])
const columnFunc = useCallback(() => {
const params = [...columns];
!disabled && params.push({
...operation,
render: (_text, record) => <>{!disabled && (
<Popconfirm
title="确认要删除吗?"
onConfirm={() => confirm(record)}
okText="是"
cancelText="否"
>
<Button type="link">删除</Button>
</Popconfirm>
)}</>
})
return params
}, [member])
return (
<CardLayout
id="invoiceType"
......@@ -84,13 +131,13 @@ const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
classNames={styles['invoice-type']}
>
<Form.Item
name='invoiceType'
name='allMembers'
initialValue={1}
rules={[
{ required: true, message: '请选择适用会员' },
]}
>
<Radio.Group>
<Radio.Group disabled={disabled}>
{mock.map(_item => (
<Radio key={_item.value} value={_item.value}>{_item.label}</Radio>
))}
......@@ -98,20 +145,17 @@ const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.invoiceType !== currentValues.invoiceType}
shouldUpdate={(prevValues, currentValues) => prevValues.allMembers !== currentValues.allMembers}
>
{({ getFieldValue }) =>
getFieldValue('invoiceType') === 2 ? (
getFieldValue('allMembers') === 2 ? (
<Space direction='vertical'>
<Button block type='dashed' icon={<PlusOutlined />} onClick={() => toggle(true)}>选择</Button>
<Form.Item name="menberId" rules={[{ required: true, message: '请选择适用会员' }]}>
{!disabled && (<Button block type='dashed' icon={<PlusOutlined />} onClick={() => toggle(true)}>选择</Button>)}
<Form.Item name="members" rules={[{ required: true, message: '请选择适用会员' }]}>
<Table
columns={[
...columns,
{
...operation
}
]}
rowKey='id'
columns={columnFunc()}
dataSource={member}
/>
</Form.Item>
</Space>
......@@ -169,7 +213,7 @@ const InvoiceTypeLayout: React.FC<InvoiceTypeProps> = (props: any) => {
}
}
}}
value={[member]}
value={member}
/>
</CardLayout>
)
......
......@@ -7,11 +7,11 @@ import { validatorByte } from '@/utils/regExp';
interface ProcessEngProps {
/** FormInstance */
form?: FormInstance,
disabled?: boolean
}
const ProcessEngLayout: React.FC<ProcessEngProps> = (props: any) => {
const { form } = props;
const { form, disabled } = props;
return (
<CardLayout
......@@ -30,7 +30,7 @@ const ProcessEngLayout: React.FC<ProcessEngProps> = (props: any) => {
{ validator: (rule, value, callback) => validatorByte(rule, value, callback, 48) }
]}
>
<Input placeholder='最长48个字符,24个汉字' />
<Input disabled={disabled} placeholder='最长48个字符,24个汉字' />
</Form.Item>
</Col>
</Row>
......
import React from 'react';
import { Form, Radio, Space } from 'antd';
import React, { useEffect, useState } from 'react';
import { Form, message, Radio, Skeleton, Space } from 'antd';
import { FormInstance } from 'antd/es/form/Form';
import CardLayout from '../card';
import styles from './index.less';
import { getSettleAccountsBusinessApplyAmountProcessBaseList, GetSettleAccountsBusinessApplyAmountProcessBaseListResponse } from '@/services/SettleV2Api';
interface ProcessSelectProps {
/** FormInstance */
form?: FormInstance,
onFieldsChange?: (value) => void,
disabled?: boolean,
}
const ProcessSelectLayout: React.FC<ProcessSelectProps> = (props: any) => {
const { form, onFieldsChange, disabled } = props;
const [dataSource, setDataSource] = useState<GetSettleAccountsBusinessApplyAmountProcessBaseListResponse>([])
const { form } = props;
const mock = [
{ id: 1, name: '请款单流程--0级', value: '-', tag: '请款单流程' },
{ id: 2, name: '请款单流程--1级', value: '1-待提交请款单', tag: '请款单流程' },
{ id: 3, name: '请款单流程--2级', value: '1-待审核请款单(一级) —>2-待提交请款单', tag: '请款单流程' },
{ id: 4, name: '请款单流程--3级', value: '1-待审核请款单(一级) —>2-审核请款单(二级)—>3-待提交请款单', tag: '请款单流程' },
]
useEffect(() => {
getSettleAccountsBusinessApplyAmountProcessBaseList().then(res => {
if (res.code !== 1000) {
message.error(res.message)
return
}
onFieldsChange(form)
setDataSource(res.data)
})
}, [])
return (
<CardLayout
......@@ -28,26 +35,31 @@ const ProcessSelectLayout: React.FC<ProcessSelectProps> = (props: any) => {
bodyStyle={{ paddingBottom: '1px' }}
classNames={styles['select-box']}
>
<Form.Item
name='processSelect'
rules={[
{ required: true, message: '请选择流程' },
]}
>
<Radio.Group>
{mock.map(_item => (
<Radio key={_item.id} value={_item.id}>
<div className={styles['box']}>
<div className={styles['box-clerk']}>
<div className={styles['box-clerk-name']}>{_item.name}</div>
<div className={styles['box-clerk-value']}>{_item.value}</div>
</div>
<div className={styles['box-tag']}>{_item.tag}</div>
</div>
</Radio>
))}
</Radio.Group>
</Form.Item>
{
JSON.stringify(dataSource) !== '[]' ? (
<Form.Item
name='baseProcessId'
rules={[
{ required: true, message: '请选择流程' },
]}
>
<Radio.Group disabled={disabled}>
{dataSource.map(_item => (
<Radio key={_item.baseProcessId} value={_item.baseProcessId}>
<div className={styles['box']}>
<div className={styles['box-clerk']}>
<div className={styles['box-clerk-name']}>{_item.processName}</div>
<div className={styles['box-clerk-value']}>{_item.description}</div>
</div>
<div className={styles['box-tag']}>{_item.processTypeName}</div>
</div>
</Radio>
))}
</Radio.Group>
</Form.Item>
) : (
<Skeleton active />
)}
</CardLayout>
)
}
......
import React from 'react';
import React, { useRef, useState } from 'react';
import { history, Link } from 'umi';
import { Button, Switch } from 'antd';
import { Button, message, Popconfirm, Switch } from 'antd';
import moment from 'moment';
import { PlusOutlined } from '@ant-design/icons';
import TableLayout from '@/components/TableLayout';
import { ColumnType } from 'antd/lib/table/interface';
import { createTime, id, name, operation, processName, status } from './columns';
import { getSettleAccountsBusinessApplyAmountProcessDelete, getSettleAccountsBusinessApplyAmountProcessPage, postSettleAccountsBusinessApplyAmountProcessStatusUpdate } from '@/services/SettleV2Api';
const InvoiceProcessEng: React.FC<{}> = () => {
const ref = useRef<any>({});
const format = (text, fmt?: string) => {
return <>{moment(text).format(fmt || "YYYY-MM-DD HH:mm:ss")}</>
}
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
const mock = [
{
id: 1,
name: '物料对账单请款流程',
processName: '请款单流程-2级',
createTime: 1650614111890,
status: 1,
/** 修改状态 */
const handleChecked = (record) => {
let status = (record.status === 1 ? 0 : 1);
const params = {
processId: record.processId,
status: status
}
]
postSettleAccountsBusinessApplyAmountProcessStatusUpdate({ ...params }).then(res => {
if (res.code !== 1000) {
message.error(res.message)
return
}
ref.current.reload()
})
}
const fetchDeleteBatch = (processId) => {
getSettleAccountsBusinessApplyAmountProcessDelete({ processId }).then(res => {
if (res.code !== 1000) {
message.error(res.message)
return
}
ref.current.reload();
})
}
const columns: ColumnType<any>[] = [
{
......@@ -29,7 +47,7 @@ const InvoiceProcessEng: React.FC<{}> = () => {
},
{
...name,
render: (_text) => <Link to='#'>{_text}</Link>
render: (_text, record) => <Link to={`/system/ruleSettingManager/invoiceProcessEng/preview?processId=${record.processId}`}>{_text}</Link>
},
{
...processName,
......@@ -40,21 +58,28 @@ const InvoiceProcessEng: React.FC<{}> = () => {
},
{
...status,
render: (_text) => <Switch checked={!!_text} />
render: (_text, record) => <Switch checked={!!_text} onChange={() => handleChecked(record)} />
},
{
...operation,
render: (_text) => <>
<Button type='link'>编辑</Button>
<Button type='link'>删除</Button>
render: (_text, record) => <>
{!!!record.status &&
<>
<Button type='link' href={`/system/ruleSettingManager/invoiceProcessEng/edit?processId=${record.processId}`} >编辑</Button>
<Popconfirm okButtonProps={{ loading: deleteLoading }} title='确定删除么?' okText='是' cancelText='否' onConfirm={() => fetchDeleteBatch(record.processId)}>
<Button type='link'>删除</Button>
</Popconfirm>
</>
}
</>
},
]
return (
<TableLayout
reload={ref}
columns={columns}
fetch={mock}
fetch={getSettleAccountsBusinessApplyAmountProcessPage}
schema={{
type: "object",
properties: {
......
import { isEmpty } from '@formily/antd/esm/shared';
import React, { useState } from 'react';
const useFields = () => {
const [percent, setPercent] = useState<number>(0);
/**计算输入框输入了百分之多少 */
const onFieldsChange = (form) => {
const allValues = form.getFieldsValue();
const values = Object.values(allValues);
console.log(allValues, 'allValues')
let num = 0;
values.forEach(_item => {
if (_item && !isEmpty(_item)) {
num += 1
}
})
setPercent(Number(((num / values.length) * 100)))
}
return {
percent,
onFieldsChange
}
}
export default useFields
......@@ -16,7 +16,7 @@ const tokenList = [
{ name: 'ManageV2', token: '0c0eb3719da2751a0acf843f5416ca950115f524013ec6a2e163e55c754b4518', categoryIds: [0] }, // 平台后台v2
{ name: 'MemberV2', token: '7f9275059dca64485b5a21e0eb6f5cd0dddc9e30c5b03059471403fc5de82413', categoryIds: [0] }, //会员服务 V2
{ name: 'ReportV2', token: 'a0be98fff3a0d003cf04fb066cdca89a832fdcbf8d7cfd19a2e34f710088aadc', categoryIds: [0] }, // 报表服务v2
{ name: 'SettleV2', token: '47a1140c81879627e572bc52110ee0adcdc78c643a64f71c372effb35a026188', categoryIds: [0] }, //结算服务v2
{ name: 'SettleV2', token: '6f7d802cb60ffe7eae5e199db8b70a8ec9f26837ec56b578a747520054be0a42', categoryIds: [0] }, //结算服务v2-220518
{ name: 'MessageV2', token: '6dd48310418fa369d74b9d197e01b210703301060ae0fe11837e4f70a1278bd3', categoryIds: [0] }, // 消息服务v2
{ name: 'LogisticsV2', token: '5b6895dc979cdfab94633c2e4560a93447433a9d6fd21a104cc7172de4a4ca37', categoryIds: [0] }, // 物流服务V2
{ name: 'TransactionV2', token: 'd2c967e2d0ee89056d3ff01ba9e95c0444e53a3080ca6c4f0115e0cebc9dc76b', categoryIds: [0] }, // 交易服务v2
......
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