Commit 079f7d69302789198cac9958b186c9a04f3412f3

Authored by 张志伟
2 parents b000b1a3 1a951613

Merge remote-tracking branch 'origin/bug_fix'

src/pages/attendance/Attend/subpages/AttendanceGroup/api.ts
... ... @@ -15,6 +15,8 @@ export interface Item {
15 15 // timeList: timeList[];
16 16 shops?: Shop[];
17 17 posts?: Post[];
  18 + morningRatio?: number; // 早班比例
  19 + nightRatio?: number; // 晚班比例
18 20 }
19 21  
20 22 export interface ClockInCycles {
... ...
src/pages/attendance/Attend/subpages/AttendanceGroup/components/GroupModal.tsx
1 1 import React, { useEffect, useState } from 'react';
2   -import { Modal, Form, Select, message, Radio, Input, Spin } from 'antd';
  2 +import type { RadioChangeEvent, SliderSingleProps } from 'antd';
  3 +import { Modal, Form, Select, message, Radio, Input, Spin, Slider, Row, InputNumber } from 'antd';
3 4 import GroupDetail from './GroupDetail/index';
4 5 import * as API from '../api';
5 6 import ShopSelectNew from '@/components/ShopSelectNew';
... ... @@ -86,12 +87,26 @@ export default function GroupModal(props: Props) {
86 87 width="60%"
87 88 >
88 89 <Spin spinning={confirmLoading}>
89   - <Form form={form} onFinish={submit} labelCol={{ span: 6 }} wrapperCol={{ span: 20 }}>
  90 + <Form form={form} onFinish={submit} labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
90 91 <Form.Item name="attendanceGroupName" label="考勤组名称" rules={[{ required: true, message: '请输入考勤组名称' }]}>
91 92 <Input style={{ width: '100%' }} />
92 93 </Form.Item>
93 94  
94   - <FormItem name="common" label="是否集团通用配置" rules={[{ required: true, message: '请选择集团通用配置' }]}>
  95 + <FormItem
  96 + name="common"
  97 + label="是否集团通用配置"
  98 + rules={[{ required: true, message: '请选择集团通用配置' }]}
  99 + getValueFromEvent={(e: RadioChangeEvent) => {
  100 + form.setFieldsValue({
  101 + shops: [],
  102 + posts: [],
  103 + clockInCycles: [],
  104 + morningRatio: undefined,
  105 + nightRatio: undefined,
  106 + });
  107 + return e.target.value;
  108 + }}
  109 + >
95 110 <Radio.Group>
96 111 <Radio value>是</Radio>
97 112 <Radio value={false}>否</Radio>
... ... @@ -109,17 +124,19 @@ export default function GroupModal(props: Props) {
109 124 label="班组类型"
110 125 rules={[{ required: true, message: '班组类型' }]}
111 126 getValueFromEvent={(name) => {
112   - form.setFieldValue(
113   - 'clockInCycles',
114   - name === 1
115   - ? ([{ cycleType: 1, cycleName: '正常班次' }] as API.ClockInCycles[])
116   - : name === 2
117   - ? ([
118   - { cycleType: 2, cycleName: '早班' },
119   - { cycleType: 3, cycleName: '晚班' },
120   - ] as API.ClockInCycles[])
121   - : [],
122   - );
  127 + form.setFieldsValue({
  128 + clockInCycles:
  129 + name === 1
  130 + ? ([{ cycleType: 1, cycleName: '正常班次' }] as API.ClockInCycles[])
  131 + : name === 2
  132 + ? ([
  133 + { cycleType: 2, cycleName: '早班' },
  134 + { cycleType: 3, cycleName: '晚班' },
  135 + ] as API.ClockInCycles[])
  136 + : [],
  137 + morningRatio: name == 2 ? 50 : undefined,
  138 + nightRatio: name == 2 ? 50 : undefined,
  139 + });
123 140 return name;
124 141 }}
125 142 >
... ... @@ -134,6 +151,41 @@ export default function GroupModal(props: Props) {
134 151 <Form.Item name="posts" label="适用岗位" rules={[{ required: true, message: '请选择' }]}>
135 152 <PostSelectNew multiple labelInValue />
136 153 </Form.Item>
  154 + <Form.Item noStyle shouldUpdate={(prev, cur) => prev.name !== cur.name}>
  155 + {({ getFieldValue }) => {
  156 + const name: number | undefined = getFieldValue('name');
  157 + if (name == 2) {
  158 + return (
  159 + <>
  160 + <Form.Item
  161 + name="morningRatio"
  162 + label="早班比例"
  163 + rules={[{ required: true, message: '请配置' }]}
  164 + getValueFromEvent={(ratio) => {
  165 + form.setFieldValue('nightRatio', 100 - ratio);
  166 + return ratio;
  167 + }}
  168 + >
  169 + <SliderItem unit="%" min={0} max={100} marks={{ 0: '0%', 25: '25%', 50: '50%', 75: '75%', 100: '100%' }} />
  170 + </Form.Item>
  171 + <Form.Item
  172 + name="nightRatio"
  173 + label="晚班比例"
  174 + rules={[{ required: true, message: '请配置' }]}
  175 + getValueFromEvent={(ratio) => {
  176 + form.setFieldValue('morningRatio', 100 - ratio);
  177 + return ratio;
  178 + }}
  179 + >
  180 + <SliderItem unit="%" reverse min={0} max={100} marks={{ 0: '0%', 25: '25%', 50: '50%', 75: '75%', 100: '100%' }} />
  181 + </Form.Item>
  182 + </>
  183 + );
  184 + } else {
  185 + return null;
  186 + }
  187 + }}
  188 + </Form.Item>
137 189 </>
138 190 );
139 191 } else if (_common === true) {
... ... @@ -198,3 +250,24 @@ export default function GroupModal(props: Props) {
198 250 </Modal>
199 251 );
200 252 }
  253 +
  254 +interface SliderProps extends SliderSingleProps {
  255 + unit?: string;
  256 +}
  257 +
  258 +function SliderItem(props: SliderProps) {
  259 + return (
  260 + <Row style={{ width: '100%', gap: 20 }}>
  261 + <Slider {...props} style={{ flex: 1 }} />
  262 + <InputNumber
  263 + style={{ width: 100 }}
  264 + min={props.min ?? 0}
  265 + max={props.max ?? 100}
  266 + step={props.step ?? 1}
  267 + addonAfter={props.unit}
  268 + value={props.value}
  269 + onChange={(v) => props.onChange?.(v ?? 0)}
  270 + />
  271 + </Row>
  272 + );
  273 +}
... ...
src/pages/attendance/Attend/subpages/AttendanceGroup/components/TimeModal.tsx
1 1 import React from 'react';
2 2 import { Modal, Table } from 'antd';
3   -import type { ClockInCycles } from '@/pages/attendance/Attend/subpages/AttendanceGroup/api';
  3 +import type { ClockInCycles, Item } from '@/pages/attendance/Attend/subpages/AttendanceGroup/api';
4 4  
5 5 const { Column } = Table;
6 6 interface Props {
  7 + current: Item | undefined;
7 8 timeModal: { visible: boolean; record?: ClockInCycles[] };
8 9 onCancel: Function;
9 10 }
10 11  
11   -export default function TimeModal({ timeModal, onCancel }: Props) {
  12 +export default function TimeModal({ current, timeModal, onCancel }: Props) {
12 13 const { visible, record } = timeModal;
13 14 return (
14 15 <Modal title="打卡时间列表" open={visible} onCancel={() => onCancel()} onOk={() => onCancel()}>
15 16 {record?.map((item, index) => (
16 17 <div key={`${Date.now() + index}`} style={{ display: 'flex', flexDirection: 'column' }}>
17   - <span style={{ marginTop: 20 }}>{item.cycleName ?? '打卡周期'}</span>
  18 + <span style={{ marginTop: 20 }}>
  19 + {item.cycleName ?? '打卡周期'}
  20 + {current?.name == 2 && item.cycleType == 2 ? <span style={{ fontSize: 12, color: '#666' }}>({current.morningRatio}%)</span> : null}
  21 + {current?.name == 2 && item.cycleType == 3 ? <span style={{ fontSize: 12, color: '#666' }}>({current.nightRatio}%)</span> : null}
  22 + </span>
18 23 <Table dataSource={item.cycles || []} rowKey="clockBeginTime" pagination={false}>
19 24 <Column title="打卡时间" dataIndex="clockBeginTime" key="clockBeginTime" />
20 25 <Column title="待办通知类型" dataIndex="noticeTypeDesc" key="noticeTypeDesc" />
... ...
src/pages/attendance/Attend/subpages/AttendanceGroup/index.tsx
... ... @@ -9,7 +9,7 @@ import ShopModal from &#39;@/pages/attendance/components/ShopModal&#39;;
9 9 import TimeModal from './components/TimeModal';
10 10 import useMenuElement from '@/hooks/useMenuElement';
11 11 import TableArrayColumnFormat from '@/pages/ehr/components/TableArrayColumnFormat';
12   -import type { ClockInCycles } from './api';
  12 +import type { ClockInCycles, Item } from './api';
13 13  
14 14 const Column = Table.Column;
15 15 const defaultModal = {
... ... @@ -23,7 +23,7 @@ const defaultModal = {
23 23 const AttendanceGroup = () => {
24 24 const { elements } = useMenuElement();
25 25 const { list, loading, setLoading } = usePagination<API.Item>(API.fetchList, undefined);
26   - const [current, setCurrent] = useState<any>();
  26 + const [current, setCurrent] = useState<Item>();
27 27 const [visivle, setVisible] = useState(false);
28 28 const [timeModal, setTimeModal] = useState<{
29 29 visible: boolean;
... ... @@ -93,17 +93,18 @@ const AttendanceGroup = () =&gt; {
93 93 <Column
94 94 dataIndex="clockInCycles"
95 95 title="打卡时间列表"
96   - render={(timeList: ClockInCycles[]) =>
  96 + render={(timeList: ClockInCycles[], record: Item) =>
97 97 timeList ? (
98 98 timeList.length ? (
99 99 <Button
100 100 type="link"
101   - onClick={() =>
  101 + onClick={() => {
  102 + setCurrent(record);
102 103 setTimeModal({
103 104 visible: true,
104 105 record: timeList,
105   - })
106   - }
  106 + });
  107 + }}
107 108 >
108 109 查看
109 110 </Button>
... ... @@ -150,7 +151,14 @@ const AttendanceGroup = () =&gt; {
150 151 </Card>
151 152 </div>
152 153 <ShopModal shopModal={shopModal} onCancel={() => setShopModal(defaultModal)} />
153   - <TimeModal timeModal={timeModal} onCancel={() => setTimeModal({ visible: false, record: [] })} />
  154 + <TimeModal
  155 + timeModal={timeModal}
  156 + current={current}
  157 + onCancel={() => {
  158 + setTimeModal({ visible: false, record: [] });
  159 + setCurrent(undefined);
  160 + }}
  161 + />
154 162 </Card>
155 163 <GroupModal visible={visivle} setVisible={setVisible} current={current} setCurrent={setCurrent} setLoading={setLoading} />
156 164 </PageHeaderWrapper>
... ...
src/pages/performance/EvaGroupSetting/EditComfirm/components/LadderParams.tsx
... ... @@ -34,8 +34,9 @@ const LadderParams = ({ postId, shopIds, value, onChange, setItemId, isHundred,
34 34 }, []);
35 35 useEffect(() => {
36 36 if (indicatorsList && indicatorsList.length > 0) {
37   - const res = indicatorsList.filter((item) => !selectedIndicatorsLadder.find((y) => y === item.code));
38   - setNewIndicators([...res]);
  37 + // fixme 这里有问题,限制在整个排名组了。实际上只能在单个组里。暂时不做限制,需要调整
  38 + // const res = indicatorsList.filter((item) => !selectedIndicatorsLadder.find((y) => y === item.code));
  39 + setNewIndicators([...indicatorsList]);
39 40 }
40 41 }, [indicatorsList]);
41 42 // 编辑
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/AddIndicatorsModal.tsx
1   -/* eslint-disable no-return-assign */
2   -/* eslint-disable no-return-assign */
3 1 import React, { useEffect, useState } from 'react';
4 2 import { Modal, Form, Select, InputNumber, message, Spin, Radio, Input, Button } from 'antd';
5   -import { saveRewardsListApi } from '../RewardsList/api';
6 3 import { useStore } from '../index';
7   -import { queryPostIndicatorApi } from '../api';
8 4 import _ from 'lodash';
9   -import useInitail from '@/hooks/useInitail';
10 5 import LadderTable from './LadderTable';
11 6 import CommissionParams from '@/pages/performance/KpiGroupSetting/EditComfirm/components/CommissionParams';
12 7 import LadderParams from '@/pages/performance/KpiGroupSetting/EditComfirm/components/LadderParams';
13 8 import Conds from '@/pages/performance/KpiGroupSetting/EditComfirm/components/Conds';
14   -import { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
  9 +import type { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
15 10  
16 11 const Option = Select.Option;
17 12 interface Props {
18 13 visible: boolean;
19   - onCancel: Function;
  14 + onCancel: () => void;
20 15 postId?: number;
21 16 shopIds?: string;
22 17 onOk: (vales: any) => void;
... ... @@ -66,7 +61,6 @@ export default function AddIndicatorsModal(props: Props) {
66 61 // }, [indicatorsList]);
67 62 // 校验表单数据
68 63 function transformDTO(formData: any) {
69   - console.log('InformData', formData);
70 64 const detail = {};
71 65 _.each(formData, (value: any, key: string) => {
72 66 switch (key) {
... ... @@ -122,7 +116,6 @@ export default function AddIndicatorsModal(props: Props) {
122 116 Object.assign(item, { sort: index + 1 });
123 117 });
124 118 }
125   - console.log('cond', pa?.conds);
126 119  
127 120 // 校验标准分不能大于绩效分值
128 121 const indicatorValue = pa.baseScore;
... ... @@ -142,18 +135,9 @@ export default function AddIndicatorsModal(props: Props) {
142 135 }
143 136 }
144 137  
145   - const newItemId = pa.id;
146   - // 编辑时,不需要push id
147   - // if (currentItem.id) {
148   - // const tmpIds = [...selectedIndicators];
149   - // tmpIds.push(newItemId);
150   - // setSelectedIndicators([...tmpIds]);
151   - // setSelectedIndicatorsConds([...tmpIds]);
152   - // }
153 138 if (hundred === 100) {
154 139 setIsHundred(false);
155 140 onOk(pa);
156   - console.log(pa);
157 141 onCancel && onCancel();
158 142 } else {
159 143 setIsHundred(true);
... ... @@ -178,7 +162,7 @@ export default function AddIndicatorsModal(props: Props) {
178 162 return (
179 163 <Modal
180 164 title={`${currentItem.name ? '编辑' : '新增'}指标`}
181   - visible={visible}
  165 + open={visible}
182 166 maskClosable={false}
183 167 afterClose={() => {
184 168 form.resetFields();
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/AddKpiGroups.tsx
... ... @@ -2,10 +2,11 @@ import React, { useEffect, useState, useRef } from &quot;react&quot;;
2 2 import { Modal, Form, Select, message, Radio, Input } from "antd";
3 3 import { useStore } from "../index";
4 4 import _ from "lodash";
5   -import { KpiGroupSetteing } from "@/pages/performance/KpiGroupSetting/interface";
6   -import ShopSelectNew, { ShopSelectNewRef } from "@/components/ShopSelectNew";
  5 +import type { KpiGroupSetteing } from "@/pages/performance/KpiGroupSetting/interface";
  6 +import type { ShopSelectNewRef } from "@/components/ShopSelectNew";
  7 +import ShopSelectNew from "@/components/ShopSelectNew";
7 8 import { transformDTO, transformFormData } from "../../entity";
8   -import { ShopList } from "../api";
  9 +import type { ShopList } from "../api";
9 10 import * as api from "../api";
10 11 import IndivatorsTable from './IndivatorsTable';
11 12 import PersonModal from "../../components/PersonModal";
... ... @@ -15,7 +16,7 @@ import useInitail from &#39;@/hooks/useInitail&#39;;
15 16 const Option = Select.Option;
16 17 interface Props {
17 18 visible: boolean;
18   - onCancel: Function;
  19 + onCancel: () => void;
19 20 onOk: (vales: any) => void;
20 21 kpiGroupsItem: KpiGroupSetteing.KpiGroupDetail;
21 22 }
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/CommissionParams.tsx
... ... @@ -55,8 +55,9 @@ const CommissionParams = ({ postId, shopIds, value, onChange, setItemId, isHundr
55 55 }, [value]);
56 56 useEffect(() => {
57 57 if (indicatorsList && indicatorsList.length > 0) {
58   - const res = indicatorsList.filter((item) => !selectedIndicators.find((y) => y === item.indicatorCode));
59   - setNewIndicators([...res]);
  58 + // fixme 这里有问题,限制在整个排名组了。实际上只能在单个组里。暂时不做限制,需要调整
  59 + // const res = indicatorsList.filter((item) => !selectedIndicators.find((y) => y === item.indicatorCode));
  60 + setNewIndicators([...indicatorsList]);
60 61 }
61 62 }, [indicatorsList]);
62 63 // console.log('selectedIndicators', selectedIndicators);
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/IndivatorsTable.tsx
1 1 import React, { useState, useEffect } from 'react';
2 2 import { Table, Typography, Button, message, Card, Divider, Space } from 'antd';
3   -import Column from 'antd/lib/table/Column';
4 3 import AddIndicatorsModal from './AddIndicatorsModal';
5   -import { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
  4 +import type { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
6 5 import LadderTable from '@/pages/performance/KpiGroupSetting/EditComfirm/components/LadderTable';
7 6 import { useStore } from '../index';
8 7 import TargetModal from './TargetModal';
9 8  
10 9 interface Props {
11 10 value?: any[];
12   - onChange?: Function;
  11 + onChange?: () => void;
13 12 postId?: number;
14 13 personModal: KpiGroupSetteing.Person;
15 14 }
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/KpiGroups.tsx
1 1 import React, { useState, useEffect } from 'react';
2 2 import { Table, Typography, Button, Card, Divider, Space } from 'antd';
3   -import { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
  3 +import type { KpiGroupSetteing } from '@/pages/performance/KpiGroupSetting/interface';
4 4 import { useStore } from '../index';
5 5 import EmployeesModal from '../../components/EmployeesModal';
6 6 import ShopModal from '../../components/ShopModal';
... ... @@ -8,11 +8,10 @@ import AddKpiGroups from &#39;./AddKpiGroups&#39;;
8 8  
9 9 interface Props {
10 10 value?: any[];
11   - onChange?: Function;
  11 + onChange?: () => void;
12 12 }
13 13  
14 14 type Item = KpiGroupSetteing.KpiGroupDetail;
15   -type CommissionParams = KpiGroupSetteing.CommissionParams;
16 15 const IndivatorsTable = ({ value, onChange }: Props) => {
17 16 const { readOnly, setSelectedIndicators } = useStore();
18 17 const [tableData, setTableData] = useState<Item[]>(value || []);
... ... @@ -57,7 +56,6 @@ const IndivatorsTable = ({ value, onChange }: Props) =&gt; {
57 56 };
58 57 //复制
59 58 const onCopy = (record: Item, index: number) => {
60   - console.log('kpirecord', record);
61 59 tableData.push({ ...record, index: tableData.length });
62 60 onChange && onChange(tableData);
63 61 };
... ... @@ -65,7 +63,6 @@ const IndivatorsTable = ({ value, onChange }: Props) =&gt; {
65 63 const onEdit = (record: Item, index: number) => {
66 64 setVisible(true);
67 65 setKpiGroupsItem({ ...record, index });
68   - console.log({ ...record, index });
69 66 };
70 67 // 删除
71 68 const _onDelete = (record: Item, index: number) => {
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/components/LadderParams.tsx
... ... @@ -52,8 +52,9 @@ const LadderParams = ({ postId, shopIds, value, onChange, setItemId, isHundred }
52 52 }, [value]);
53 53 useEffect(() => {
54 54 if (indicatorsList && indicatorsList.length > 0) {
55   - const res = indicatorsList.filter((item) => !selectedIndicatorsLadder.find((y) => y === item.indicatorCode));
56   - setNewIndicators([...res]);
  55 + // fixme 这里有问题,限制在整个排名组了。实际上只能在单个组里。暂时不做限制,需要调整
  56 + // const res = indicatorsList.filter((item) => !selectedIndicatorsLadder.find((y) => y === item.indicatorCode));
  57 + setNewIndicators([...indicatorsList]);
57 58 }
58 59 }, [indicatorsList]);
59 60 const onCancel = () => {
... ...
src/pages/performance/KpiGroupSetting/EditComfirm/index.tsx
1 1 import React, { useEffect, useState, useMemo } from 'react';
2 2 import { Card, Popconfirm, Row, Button, message, Result, Form, Radio, Input, Select } from 'antd';
3 3 import { FeeweeFileAccept, FeeweeFileChange } from '@/utils/getFidFile';
4   -import type { common } from '@/typing/common';
5 4 import { PlusOutlined } from '@ant-design/icons';
6 5 import { IMGURL } from '@/utils';
7 6 import { PageHeaderWrapper } from '@ant-design/pro-layout';
... ... @@ -16,15 +15,14 @@ import moment from &#39;moment&#39;;
16 15 import KpiGroups from './components/KpiGroups';
17 16 import PreviewRrport from './components/PreviewReport';
18 17 import _ from 'lodash';
19   -import useInitial from '@/hooks/useInitail';
20   -import { fetchRealtimeStaffs } from '../api';
  18 +import type { ConnectProps } from '@/typing/common';
21 19  
22 20 const Option = Select.Option;
23 21  
24 22 // 星级数据:
25 23 export const { Provider, useStore } = createStore(store);
26 24  
27   -type Props = common.ConnectProps;
  25 +type Props = ConnectProps;
28 26 function Index(props: Props) {
29 27 const { detailError, configId, setId, data, readOnly, setReadOnly, setSubmit, loading, kpiGroups, setKpiGroups } = useStore();
30 28 const [form] = Form.useForm();
... ...