Commit b03cc5630320a08adec25609c7cc0791532a8f09
1 parent
96ee8bdc
feat(contract): 合同系统增加就餐白名单菜单功能
Showing
6 changed files
with
277 additions
and
2 deletions
config/routers/contract.ts
src/pages/contract/ExpressLogisticsArticleSetting/components/UserAddModal.tsx
... | ... | @@ -40,7 +40,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro |
40 | 40 | name="userName" |
41 | 41 | rules={[ |
42 | 42 | { required: true, message: '请填写姓名' }, |
43 | - { max: 20, message: '输入长度应该小于20' }, | |
43 | + { max: 32, message: '输入长度应该小于32' }, | |
44 | 44 | { whitespace: true, message: '不能输入空白字符' }, |
45 | 45 | ]} |
46 | 46 | > |
... | ... | @@ -55,7 +55,7 @@ export default function UserAddModal({ visible, value, onCancel, onChange }: Pro |
55 | 55 | pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/, |
56 | 56 | message: '请输入有效的电话号码', |
57 | 57 | }, |
58 | - { max: 20, message: '输入长度应该小于20' }, | |
58 | + { max: 16, message: '输入长度应该小于16' }, | |
59 | 59 | { whitespace: true, message: '不能输入空白字符' }, |
60 | 60 | ]} |
61 | 61 | > | ... | ... |
src/pages/contract/FoodWhiteList/api.ts
0 → 100644
1 | +import type { http } from '@/typing/http'; | |
2 | +import request from '@/utils/request'; | |
3 | +import { OA_HOST } from '@/utils/host'; | |
4 | +import type { Pagination } from '@/typing/common'; | |
5 | + | |
6 | +export interface Item { | |
7 | + id?: number; | |
8 | + name: string; | |
9 | + mobile: string; | |
10 | + remark: string; | |
11 | +} | |
12 | + | |
13 | +export interface PageParams extends Pagination { | |
14 | + name?: string; | |
15 | + mobile?: string; | |
16 | + remark?: string; | |
17 | +} | |
18 | + | |
19 | +/** | |
20 | + * 分页查询 | |
21 | + */ | |
22 | +export function getFoodWhitePage(params?: PageParams): http.PromisePageResp<Item> { | |
23 | + return request.get(`${OA_HOST}/contract/erp/repast/white/page`, { params }); | |
24 | +} | |
25 | + | |
26 | +/** | |
27 | + * 新增/编辑 | |
28 | + */ | |
29 | +export function addFoodWhite(data?: Item): http.PromiseResp<void> { | |
30 | + return request.post(`${OA_HOST}/contract/erp/repast/white/save`, data); | |
31 | +} | |
32 | + | |
33 | +/** | |
34 | + * 删除 | |
35 | + */ | |
36 | +export function delFoodWhite(id: number): http.PromisePageResp<void> { | |
37 | + return request.post(`${OA_HOST}/contract/erp/repast/white/delete`, { id }); | |
38 | +} | ... | ... |
src/pages/contract/FoodWhiteList/components/AddModal/index.tsx
0 → 100644
1 | +import React, { useEffect, memo } from 'react'; | |
2 | +import { Modal, Form, message, Input } from 'antd'; | |
3 | +import * as API from '../../api'; | |
4 | +import { useRequest } from 'umi'; | |
5 | + | |
6 | +interface Props { | |
7 | + visible: boolean; | |
8 | + row?: API.Item; | |
9 | + onCancel: () => void; | |
10 | + onRefresh: () => void; | |
11 | +} | |
12 | + | |
13 | +function AddModal({ visible, row, onCancel, onRefresh }: Props) { | |
14 | + const { id } = row ?? {}; | |
15 | + const [form] = Form.useForm(); | |
16 | + | |
17 | + const saveHook = useRequest(API.addFoodWhite, { | |
18 | + manual: true, | |
19 | + throwOnError: true, | |
20 | + }); | |
21 | + | |
22 | + useEffect(() => { | |
23 | + if (visible) { | |
24 | + if (row) { | |
25 | + form.setFieldsValue(row); | |
26 | + } | |
27 | + } else { | |
28 | + form.resetFields(); | |
29 | + } | |
30 | + }, [visible, row]); | |
31 | + | |
32 | + const handleSave = (feildValue: any) => { | |
33 | + saveHook | |
34 | + .run(feildValue) | |
35 | + .then(() => { | |
36 | + message.success('操作成功'); | |
37 | + onCancel(); | |
38 | + onRefresh(); | |
39 | + }) | |
40 | + .catch((e) => { | |
41 | + message.error(e.message); | |
42 | + }); | |
43 | + }; | |
44 | + | |
45 | + return ( | |
46 | + <Modal title={`${id ? '编辑' : '新增'}`} open={visible} confirmLoading={saveHook.loading} onCancel={onCancel} onOk={form.submit} width={600}> | |
47 | + <Form form={form} onFinish={handleSave} labelCol={{ span: 4 }} wrapperCol={{ span: 18 }}> | |
48 | + <Form.Item name="id" hidden /> | |
49 | + <Form.Item | |
50 | + label="姓名" | |
51 | + name="name" | |
52 | + rules={[ | |
53 | + { required: true, message: '请填写姓名' }, | |
54 | + { max: 32, message: '输入长度应该小于32' }, | |
55 | + { whitespace: true, message: '不能输入空白字符' }, | |
56 | + ]} | |
57 | + > | |
58 | + <Input placeholder="请填写" /> | |
59 | + </Form.Item> | |
60 | + <Form.Item | |
61 | + label="手机号" | |
62 | + name="mobile" | |
63 | + rules={[ | |
64 | + { required: true, message: '请填写联系电话' }, | |
65 | + { | |
66 | + pattern: /^((\+86)|(86))?(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/, | |
67 | + message: '请输入有效的电话号码', | |
68 | + }, | |
69 | + { max: 16, message: '输入长度应该小于16' }, | |
70 | + { whitespace: true, message: '不能输入空白字符' }, | |
71 | + ]} | |
72 | + > | |
73 | + <Input placeholder="请填写" /> | |
74 | + </Form.Item> | |
75 | + <Form.Item label="备注" name="remark" rules={[{ required: true, message: '请填写' }]}> | |
76 | + <Input.TextArea placeholder="请填写" maxLength={64} /> | |
77 | + </Form.Item> | |
78 | + </Form> | |
79 | + </Modal> | |
80 | + ); | |
81 | +} | |
82 | + | |
83 | +export default memo(AddModal); | ... | ... |
src/pages/contract/FoodWhiteList/components/Filter/index.tsx
0 → 100644
1 | +import React from 'react'; | |
2 | +import { Input, Row } from 'antd'; | |
3 | +import _ from 'lodash'; | |
4 | +import type { PageParams } from '../../api'; | |
5 | + | |
6 | +interface Props { | |
7 | + innerParams?: any; | |
8 | + setParams: (params: PageParams, refreshing: boolean) => void; | |
9 | +} | |
10 | + | |
11 | +function Filter({ innerParams, setParams }: Props) { | |
12 | + const onChange = _.debounce((newParams) => { | |
13 | + setParams({ ...innerParams, ...newParams }, true); | |
14 | + }, 600); | |
15 | + | |
16 | + return ( | |
17 | + <Row style={{ display: 'flex', flex: 1 }}> | |
18 | + <Input | |
19 | + style={{ width: 200 }} | |
20 | + allowClear | |
21 | + placeholder="搜索姓名" | |
22 | + onChange={(e) => { | |
23 | + onChange({ name: e.target.value }); | |
24 | + }} | |
25 | + /> | |
26 | + <Input | |
27 | + style={{ width: 200, marginLeft: 20 }} | |
28 | + allowClear | |
29 | + placeholder="搜索手机号" | |
30 | + onChange={(e) => { | |
31 | + onChange({ mobile: e.target.value }); | |
32 | + }} | |
33 | + /> | |
34 | + </Row> | |
35 | + ); | |
36 | +} | |
37 | + | |
38 | +export default Filter; | ... | ... |
src/pages/contract/FoodWhiteList/index.tsx
0 → 100644
1 | +import React, { useState } from 'react'; | |
2 | +import { Button, Card, ConfigProvider, Divider, message, Popconfirm, Row, Table } from 'antd'; | |
3 | +import { PageHeaderWrapper } from '@ant-design/pro-layout'; | |
4 | +import zhCN from 'antd/lib/locale-provider/zh_CN'; | |
5 | +import usePagination from '@/hooks/usePagination'; | |
6 | +import { PlusOutlined } from '@ant-design/icons'; | |
7 | +import AddModal from './components/AddModal'; | |
8 | +import Filter from './components/Filter'; | |
9 | +import * as API from './api'; | |
10 | +import _ from 'lodash'; | |
11 | + | |
12 | +const { Column } = Table; | |
13 | + | |
14 | +export default function Index() { | |
15 | + // 新增 | 编辑 | |
16 | + const [addModal, setAddModal] = useState<{ | |
17 | + visible: boolean; | |
18 | + row?: API.Item; | |
19 | + }>({ | |
20 | + visible: false, | |
21 | + }); | |
22 | + | |
23 | + const { list, paginationConfig, loading, innerParams, setParams } = usePagination<API.Item>(API.getFoodWhitePage); | |
24 | + | |
25 | + const handleDelete = (row: API.Item) => { | |
26 | + const { id } = row; | |
27 | + API.delFoodWhite(id!) | |
28 | + .then((res) => { | |
29 | + message.success(res.result); | |
30 | + setParams({ ...innerParams }, true); | |
31 | + }) | |
32 | + .catch((e) => { | |
33 | + message.error(e.message); | |
34 | + }); | |
35 | + }; | |
36 | + | |
37 | + const handleEdit = (row: API.Item) => { | |
38 | + setAddModal({ | |
39 | + visible: true, | |
40 | + row, | |
41 | + }); | |
42 | + }; | |
43 | + | |
44 | + return ( | |
45 | + <PageHeaderWrapper title="就餐白名单"> | |
46 | + <ConfigProvider locale={zhCN}> | |
47 | + <Card> | |
48 | + <Row align="middle" justify="space-between" style={{ marginBottom: 20 }}> | |
49 | + <Filter innerParams={innerParams} setParams={setParams} /> | |
50 | + <Button | |
51 | + type="primary" | |
52 | + icon={<PlusOutlined />} | |
53 | + onClick={() => { | |
54 | + setAddModal({ | |
55 | + visible: true, | |
56 | + }); | |
57 | + }} | |
58 | + > | |
59 | + 新增 | |
60 | + </Button> | |
61 | + </Row> | |
62 | + <Table | |
63 | + loading={loading} | |
64 | + dataSource={list} | |
65 | + pagination={paginationConfig} | |
66 | + rowKey="id" | |
67 | + onChange={(_pagination) => setParams({ ..._pagination }, true)} | |
68 | + > | |
69 | + <Column title="姓名" dataIndex="name" /> | |
70 | + <Column title="手机号" dataIndex="mobile" /> | |
71 | + <Column title="备注" dataIndex="remark" /> | |
72 | + <Column | |
73 | + title="操作" | |
74 | + dataIndex="btns" | |
75 | + render={(text, row: API.Item) => ( | |
76 | + <span> | |
77 | + <a | |
78 | + onClick={(e) => { | |
79 | + e.preventDefault(); | |
80 | + handleEdit(row); | |
81 | + }} | |
82 | + > | |
83 | + 编辑 | |
84 | + </a> | |
85 | + <Divider type="vertical" /> | |
86 | + <Popconfirm title="是否删除?" onConfirm={() => handleDelete(row)}> | |
87 | + <a | |
88 | + onClick={(e) => { | |
89 | + e.preventDefault(); | |
90 | + }} | |
91 | + style={{ color: 'red' }} | |
92 | + > | |
93 | + 删除 | |
94 | + </a> | |
95 | + </Popconfirm> | |
96 | + </span> | |
97 | + )} | |
98 | + /> | |
99 | + </Table> | |
100 | + </Card> | |
101 | + <AddModal | |
102 | + visible={addModal.visible} | |
103 | + row={addModal.row} | |
104 | + onCancel={() => { | |
105 | + setAddModal({ visible: false }); | |
106 | + }} | |
107 | + onRefresh={() => setParams({ ...innerParams }, true)} | |
108 | + /> | |
109 | + </ConfigProvider> | |
110 | + </PageHeaderWrapper> | |
111 | + ); | |
112 | +} | ... | ... |