Commit 6e1e695ac49f8cb56d446b489c31f8af0dc34490

Authored by 舒述军
1 parent 3b916ae7

线索到店零售占比配置

config/routers/order3.ts
... ... @@ -202,4 +202,8 @@ export default [
202 202 path: "/order3/orderSetting/deliveryVideoConfig",
203 203 component: "./order3/OrderSetting/DeliveryVideoConfig",
204 204 },
  205 + { // 零售线索占比配置
  206 + path: "/order3/retailTaskConfiguration",
  207 + component: "./order3/RetailTaskConfiguration",
  208 + },
205 209 ];
206 210 \ No newline at end of file
... ...
src/pages/order3/RetailTaskConfiguration/api.ts
... ... @@ -2,11 +2,27 @@ import { http } from '@/typing/http';
2 2 import request from '@/utils/request';
3 3 import { ORDER3 } from '@/utils/host';
4 4  
  5 +export interface List {
  6 + id?: number // id
  7 + retailRate?: number // 线索到店零售占比
  8 + shopList?: ShopList[] // 门店列表
  9 +}
  10 +
  11 +export interface ShopList {
  12 + shopId?: number // 门店id
  13 + shopName?: string // 门店名称
  14 +}
5 15 /** 获取列表 */
6   -export function getRetailListApi(params?: any): http.PromiseResp<any> {
7   - return request.get(`${ORDER3}/erp/sales/task/detail`, { params });
  16 +export function getRetailListApi(): http.PromiseResp<any> {
  17 + return request.get(`${ORDER3}/erp/clue/deal/rate/config/list`);
8 18 }
9   -// /*提交 */
10   -// export function save(id?: number) {
11   -// return request.post(`${ORDER3}/erp/sales/task/submit`, { id }, { contentType: 'form-urlencoded' });
12   -// }
13 19 \ No newline at end of file
  20 +
  21 +/* 新增编辑线索到店零售占比配置*/
  22 +export function saveRetailConfigApi(params?: List) {
  23 + return request.post(`${ORDER3}/erp/clue/deal/rate/config/save`, params);
  24 +}
  25 +
  26 +/* 删除线索到店零售占比配置*/
  27 +export function fetchDeleteConfigApi(id?: number) {
  28 + return request.post(`${ORDER3}/erp/clue/deal/rate/config/delete`, { id }, { contentType: 'form-urlencoded' });
  29 +}
14 30 \ No newline at end of file
... ...
src/pages/order3/RetailTaskConfiguration/components/EditMidal.tsx
... ... @@ -5,38 +5,63 @@ import { debounce } from &#39;lodash&#39;;
5 5 import currency from 'currency.js';
6 6 import useInitail from '@/hooks/useInitail';
7 7 import { useStore } from '../index';
  8 +import { saveRetailConfigApi } from '../api';
8 9  
9 10 const Option = Select.Option;
10 11  
11 12 export default function Index() {
12 13 const [form] = Form.useForm();
13   - const { visible, setVisible } = useStore();
  14 + const { visible, setVisible, current, setCurrent, setLoading } = useStore();
14 15 const [confirm, setConfirm] = useState<boolean>(false);
15 16  
16 17 useEffect(() => {
17   - if (visible) {
  18 + if (visible && current.id) {
18 19 handleSetValue();
19 20 }
20 21 }, [visible]);
21 22  
22 23 function handleCancle() {
23 24 setVisible(false);
  25 + setCurrent({});
24 26 }
25 27  
26 28 async function handleSubmit() {
27 29 const params = await form.validateFields();
28 30 setConfirm(true);
  31 + const _params = {
  32 + id: current.id,
  33 + retailRate: params.retailRate,
  34 + shopList: params.shopList?.map((v: any) => ({shopId: v.value, shopName: v.label}))
  35 + };
  36 + saveRetailConfigApi(_params)
  37 + .then(res => {
  38 + message.success(res.result);
  39 + setVisible(false);
  40 + setConfirm(false);
  41 + setLoading(true);
  42 + setCurrent({});
  43 + })
  44 + .catch(e => {
  45 + message.error(e.message);
  46 + setConfirm(false);
  47 + });
29 48 }
30 49  
31 50 function handleSetValue() {
32   - form.setFieldsValue({});
  51 + form.setFieldsValue({
  52 + retailRate: current.retailRate,
  53 + shopList: current.shopList?.map(v => ({label: v.shopName, value: v.shopId}))
  54 + });
33 55 }
34 56 return (
35 57 <Modal
  58 + title={current.id ? "编辑" : "新增"}
36 59 destroyOnClose
37 60 visible={visible}
38 61 maskClosable={false}
39 62 onCancel={handleCancle}
  63 + afterClose={() => form.setFieldsValue({shopList: [], retailRate: undefined})}
  64 + style={{minWidth: "500px"}}
40 65 footer={[
41 66 <Button key="cancel" onClick={handleCancle} style={{marginLeft: 10}}>取消</Button>,
42 67 <Button key="submit" onClick={handleSubmit} type="primary" htmlType="submit" loading={confirm}>确认</Button>
... ... @@ -55,29 +80,10 @@ export default function Index() {
55 80 >
56 81 <ShopSelectNew placeholder="请选择门店" multiple />
57 82 </Form.Item>
58   - {/* <Form.Item
59   - label="适用门店"
60   - name="shopList"
61   - rules={[{ required: true, message: "请选择门店" }]}
62   - >
63   - <Select
64   - optionFilterProp="children"
65   - mode="multiple"
66   - labelInValue
67   - allowClear
68   - style={{ width: "100%" }}
69   - placeholder="请选择门店"
70   - >
71   - {shop && shop.map((shop: any) => (
72   - <Option value={shop.id} key={shop.id}>
73   - {shop.shopName}
74   - </Option>
75   - ))}
76   - </Select>
77   - </Form.Item> */}
  83 +
78 84 <Form.Item
79 85 label="线索到店零售台数占比"
80   - name="shopList"
  86 + name="retailRate"
81 87 rules={[{ required: true, message: "请选择门店" }]}
82 88 >
83 89 <InputNumber
... ...
src/pages/order3/RetailTaskConfiguration/components/List.tsx
1 1 import React, { useState } from "react";
2   -import { message, Popconfirm, Table, Tooltip } from "antd";
  2 +import { message, Popconfirm, Table, Space } from "antd";
3 3 import moment from "moment";
  4 +import { useStore } from '../index';
  5 +import { fetchDeleteConfigApi, List } from '../api';
  6 +import { isNil } from 'lodash';
4 7  
5 8 const Column = Table.Column;
6 9  
7   -export default function List() {
  10 +export default function TableList() {
  11 + const {data, loading, setLoading, setVisible, setCurrent, setStatusData } = useStore();
  12 +
  13 + function handleDelete(id?: number) {
  14 + fetchDeleteConfigApi(id)
  15 + .then(res => {
  16 + message.success(res.result);
  17 + setLoading(true);
  18 + })
  19 + .catch(e => {
  20 + message.error(e.message);
  21 + });
  22 + }
  23 +
  24 + function handleEdit(value?: List) {
  25 + setCurrent(value || {});
  26 + setVisible(true);
  27 + }
  28 +
  29 + function handleLookShop(value: any = {}) {
  30 + setStatusData({visible: true, data: value.shopList || []});
  31 + }
  32 +
8 33 return (
9 34 <div>
10 35 <Table
11   - // dataSource={list}
12   - // pagination={paginationConfig}
13   - // loading={loading}
  36 + dataSource={data}
  37 + pagination={false}
  38 + loading={loading}
14 39 rowKey="id"
15 40 >
16 41 <Column
17 42 title="适用门店"
18 43 align="left"
19   - dataIndex="brandName"
  44 + dataIndex="shopList"
  45 + render={(_text, record) => <span onClick={() => handleLookShop(record)} style={{color: "#4189FD"}}>查看</span>}
20 46 />
21 47 <Column
22 48 title="线索到店零售台数占比"
23 49 align="left"
24   - dataIndex="brandName"
  50 + dataIndex="retailRate"
  51 + render={(_text, record: any) => <span>{isNil(record?.retailRate) ? "--" : `${record.retailRate}%`}</span>}
25 52 />
26 53 <Column
27 54 title="操作"
28 55 align="left"
29 56 render={(_text, record: any) => {
30 57 return (
31   - <>
32   - <a style={{ display: "block" }}>编辑</a>
  58 + <Space>
  59 + <a onClick={() => handleEdit(record)} style={{ display: "block", color: "#4189FD" }}>编辑</a>
33 60 <Popconfirm
34 61 title="是否删除?"
35 62 okText="确定"
36 63 cancelText="取消"
  64 + onConfirm={() => handleDelete(record.id)}
37 65 >
38   - <a>删除</a>
  66 + <a style={{color: "#EC3F2F"}}>删除</a>
39 67 </Popconfirm>
40   - </>
  68 + </Space>
41 69 );
42 70 }}
43 71 />
... ...
src/pages/order3/RetailTaskConfiguration/components/ShopModal.tsx 0 → 100644
  1 +import React, {useEffect, useState} from 'react';
  2 +import {Modal, Button, List} from 'antd';
  3 +import { useStore } from '../index';
  4 +import styles from '../index.less';
  5 +
  6 +export default function Index() {
  7 + const { statusData, setStatusData } = useStore();
  8 + function handleCancel() {
  9 + setStatusData({visible: false, data: []});
  10 + }
  11 +
  12 + return (
  13 + <Modal
  14 + destroyOnClose
  15 + title={<div className={styles.lineWrap}><span className={styles.line} /><span className={styles.lineText}>适用门店</span></div>}
  16 + visible={statusData.visible}
  17 + maskClosable={false}
  18 + onCancel={handleCancel}
  19 + footer={[]}
  20 + className={styles.modal}
  21 + >
  22 + <List
  23 + size="large"
  24 + style={{height: '300px', overflow: 'scroll'}}
  25 + dataSource={statusData?.data || []}
  26 + renderItem={(item: any) => <List.Item style={{justifyContent: 'center'}}>{item.shopName}</List.Item>}
  27 + />
  28 + <div
  29 + style={{
  30 + textAlign: 'center',
  31 + marginTop: 12,
  32 + height: 32,
  33 + lineHeight: '32px',
  34 + }}
  35 + ><Button type="primary" onClick={handleCancel}>返回</Button>
  36 + </div>
  37 + </Modal>
  38 + );
  39 +}
0 40 \ No newline at end of file
... ...
src/pages/order3/RetailTaskConfiguration/index.less 0 → 100644
  1 +.title {
  2 + font-size: 18px;
  3 + color: #333;
  4 + font-weight: 600;
  5 +}
  6 +
  7 +.warp {
  8 + display: flex;
  9 + direction: row;
  10 + align-items: flex-start;
  11 + justify-content: flex-start;
  12 +}
  13 +
  14 +.wrapItem {
  15 + display: inline-block;
  16 +}
  17 +
  18 +.text {
  19 + color: #333;
  20 + font-size: 14px;
  21 + font-weight: 600;
  22 +}
  23 +
  24 +.modal {
  25 + height: 400px;
  26 +}
  27 +
  28 +.line {
  29 + width: 4px;
  30 + height: 20px;
  31 + background-color: #4189FD;
  32 + border-radius: 2px;
  33 + display: inline-block;
  34 +}
  35 +
  36 +.lineText {
  37 + font-size: 18px;
  38 + color: #262626;
  39 + font-weight: bold;
  40 + display: inline-block;
  41 + margin-left: 8px;
  42 +}
  43 +
  44 +.lineWrap {
  45 + display: flex;
  46 + align-items: center;
  47 +}
  48 +
  49 +.lineSpace {
  50 + margin-bottom: 10px;
  51 +}
0 52 \ No newline at end of file
... ...
src/pages/order3/RetailTaskConfiguration/index.tsx
... ... @@ -4,6 +4,8 @@ import { PageHeaderWrapper } from &#39;@ant-design/pro-layout&#39;;
4 4 import { createStore } from '@/hooks/moz';
5 5 import store from './store';
6 6 import List from './components/List';
  7 +import ShopModal from './components/ShopModal';
  8 +import EditModal from './components/EditMidal';
7 9  
8 10 export const { Provider, useStore } = createStore(store);
9 11  
... ... @@ -12,10 +14,12 @@ function SubsidizedInterest() {
12 14 return (
13 15 <PageHeaderWrapper title="线索到店零售占比配置">
14 16 <Card>
15   - <Row justify="space-between" style={{ marginBottom: 20 }}>
  17 + <Row justify="end" style={{ marginBottom: 20 }}>
16 18 <Button type="primary" onClick={() => setVisible(true)}>新增</Button>
17 19 </Row>
18 20 <List />
  21 + <ShopModal />
  22 + <EditModal />
19 23 </Card>
20 24 </PageHeaderWrapper>
21 25 );
... ...
src/pages/order3/RetailTaskConfiguration/store.ts
1 1 import React, { useState } from 'react';
2 2 import usePagination from '@/hooks/usePagination';
3 3 import useInitial from '@/hooks/useInitail';
4   -import { getRetailListApi} from './api';
5   -import {getShopApi} from '@/common/api';
  4 +import { getRetailListApi, List, ShopList} from './api';
  5 +
  6 +interface StatusData {
  7 + visible: boolean
  8 + data: ShopList[]
  9 +}
6 10  
7 11 export default function useStore() {
8   - const { list, setParams, setLoading, loading, paginationConfig, innerParams } = usePagination(getRetailListApi, {});
  12 + const { data, setParams, setLoading, loading } = useInitial(getRetailListApi, [], null);
9 13 const [visible, setVisible] = useState<boolean>(false);
  14 + const [current, setCurrent] = useState<List>({});
  15 + const [statusData, setStatusData] = useState<StatusData>({visible: false, data: []});
10 16 return {
11   - list,
  17 + data,
12 18 setParams,
13   - innerParams,
14 19 setLoading,
15 20 loading,
16   - paginationConfig,
17 21 visible,
18   - setVisible
  22 + setVisible,
  23 + current,
  24 + setCurrent,
  25 + statusData,
  26 + setStatusData
19 27 };
20 28 }
21 29 \ No newline at end of file
... ...