|
|
@@ -1,91 +1,91 @@
|
|
|
import BasicTable from '@/components/Table'
|
|
|
+import type { RadioChangeEvent } from 'antd'
|
|
|
import { PageContainer } from '@ant-design/pro-layout'
|
|
|
-import { Input, List, Popover, Space, Tag } from 'antd'
|
|
|
+import { Input, List, Popover, Radio, Space, Tag } from 'antd'
|
|
|
import type { ColumnsType } from 'antd/lib/table'
|
|
|
-import React, { useEffect, useMemo, useRef, useState } from 'react'
|
|
|
-import { connect } from '@@/plugin-dva'
|
|
|
+import React, { useState } from 'react'
|
|
|
import Organization from './components/Organization'
|
|
|
-
|
|
|
-export type ContactsProps = {
|
|
|
- allStaffList: API.ContractList[]
|
|
|
-}
|
|
|
+import { queryStaffContacts } from '@/services/hr'
|
|
|
+import consts from '@/consts'
|
|
|
+import { isDevMode } from '@/utils/env'
|
|
|
|
|
|
const character = [
|
|
|
- { id: '1', name: '全部' },
|
|
|
- { id: '2', name: 'A' },
|
|
|
- { id: '3', name: 'B' },
|
|
|
- { id: '4', name: 'C' },
|
|
|
- { id: '5', name: 'D' },
|
|
|
- { id: '6', name: 'E' },
|
|
|
- { id: '7', name: 'F' },
|
|
|
- { id: '8', name: 'G' },
|
|
|
- { id: '9', name: 'H' },
|
|
|
- { id: '10', name: 'I' },
|
|
|
- { id: '11', name: 'J' },
|
|
|
- { id: '12', name: 'K' },
|
|
|
- { id: '13', name: 'L' },
|
|
|
- { id: '14', name: 'M' },
|
|
|
- { id: '15', name: 'N' },
|
|
|
- { id: '16', name: 'O' },
|
|
|
- { id: '17', name: 'P' },
|
|
|
- { id: '18', name: 'Q' },
|
|
|
- { id: '19', name: 'R' },
|
|
|
- { id: '20', name: 'S' },
|
|
|
- { id: '21', name: 'T' },
|
|
|
- { id: '22', name: 'U' },
|
|
|
- { id: '23', name: 'V' },
|
|
|
- { id: '24', name: 'W' },
|
|
|
- { id: '25', name: 'S' },
|
|
|
- { id: '26', name: 'Y' },
|
|
|
- { id: '27', name: 'Z' }
|
|
|
+ { value: '0', label: '全部' },
|
|
|
+ { value: 'a', label: 'A' },
|
|
|
+ { value: 'b', label: 'B' },
|
|
|
+ { value: 'c', label: 'C' },
|
|
|
+ { value: 'd', label: 'D' },
|
|
|
+ { value: 'e', label: 'E' },
|
|
|
+ { value: 'f', label: 'F' },
|
|
|
+ { value: 'g', label: 'G' },
|
|
|
+ { value: 'h', label: 'H' },
|
|
|
+ { value: 'i', label: 'I' },
|
|
|
+ { value: 'j', label: 'J' },
|
|
|
+ { value: 'k', label: 'K' },
|
|
|
+ { value: 'l', label: 'L' },
|
|
|
+ { value: 'm', label: 'M' },
|
|
|
+ { value: 'n', label: 'N' },
|
|
|
+ { value: 'o', label: 'O' },
|
|
|
+ { value: 'p', label: 'P' },
|
|
|
+ { value: 'q', label: 'Q' },
|
|
|
+ { value: 'r', label: 'R' },
|
|
|
+ { value: 's', label: 'S' },
|
|
|
+ { value: 't', label: 'T' },
|
|
|
+ { value: 'u', label: 'U' },
|
|
|
+ { value: 'v', label: 'V' },
|
|
|
+ { value: 'w', label: 'W' },
|
|
|
+ { value: 's', label: 'S' },
|
|
|
+ { value: 'y', label: 'Y' },
|
|
|
+ { value: 'z', label: 'Z' }
|
|
|
]
|
|
|
|
|
|
-const content = (
|
|
|
- <List
|
|
|
- dataSource={character}
|
|
|
- renderItem={item => (
|
|
|
- <List.Item>
|
|
|
- <List.Item.Meta title={item.name} />
|
|
|
- </List.Item>
|
|
|
- )}
|
|
|
- />
|
|
|
-)
|
|
|
-
|
|
|
-const Contacts: React.FC<ContactsProps> = props => {
|
|
|
- const { dispatch, allStaffList = [] } = props
|
|
|
- const tRef = useRef()
|
|
|
+const Contacts: React.FC<ContactsProps> = () => {
|
|
|
const [state, setState] = useState({
|
|
|
- departmentId: '0',
|
|
|
+ data: [],
|
|
|
+ birthdayMonth: [],
|
|
|
+ birthdayDay: [],
|
|
|
+ type: null,
|
|
|
params: {
|
|
|
+ departmentId: '0',
|
|
|
search: null
|
|
|
- }
|
|
|
+ },
|
|
|
+ radioValue: '0'
|
|
|
})
|
|
|
|
|
|
- const initData = () => {
|
|
|
- dispatch({
|
|
|
- type: 'staff/fetchStaffList'
|
|
|
- })
|
|
|
- }
|
|
|
- const dataSource = useMemo(() => {
|
|
|
- if (state.departmentId === '0') {
|
|
|
- return allStaffList
|
|
|
- }
|
|
|
- return allStaffList.filter(item => item.departmentId === state.departmentId)
|
|
|
- }, [state.departmentId, allStaffList])
|
|
|
+ const content = (
|
|
|
+ <List
|
|
|
+ itemLayout="horizontal"
|
|
|
+ style={{ maxHeight: '200px', overflow: 'auto' }}
|
|
|
+ dataSource={state.type === 'birthdayMonth' ? state.birthdayMonth : state.birthdayDay}
|
|
|
+ renderItem={item => (
|
|
|
+ <div className="flex items-center py-1">
|
|
|
+ <span
|
|
|
+ className="rounded-1/2 inline-block w-5 h-5 flex items-center"
|
|
|
+ style={{
|
|
|
+ backgroundImage: `url(${
|
|
|
+ (isDevMode() ? 'http://cld2qa.com' : window.location.origin) +
|
|
|
+ (item.avatar ?? consts.DEFAULT_AVATAR)
|
|
|
+ })`,
|
|
|
+ backgroundSize: 'cover'
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <span className="ml-2">{item.username}</span>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ )
|
|
|
|
|
|
- useEffect(() => {
|
|
|
- if (!allStaffList.length) {
|
|
|
- initData()
|
|
|
- }
|
|
|
- }, [])
|
|
|
const onSelect = id => {
|
|
|
- setState({ ...state, departmentId: id })
|
|
|
+ setState({ ...state, params: { departmentId: id } })
|
|
|
}
|
|
|
const handleSearch = value => {
|
|
|
- tRef.current?.reloadAndRest()
|
|
|
setState({ ...state, params: { ...state.params, search: value } })
|
|
|
}
|
|
|
|
|
|
+ const onChangeHandle = ({ target: { value } }: RadioChangeEvent) => {
|
|
|
+ setState({ ...state, radioValue: value, params: { ...state.params, search: value } })
|
|
|
+ }
|
|
|
+
|
|
|
const columns: ColumnsType<API.ContractItem> = [
|
|
|
{
|
|
|
title: '字母',
|
|
|
@@ -141,70 +141,128 @@ const Contacts: React.FC<ContactsProps> = props => {
|
|
|
<div className="flex flex-row">
|
|
|
<Organization onSelect={onSelect} />
|
|
|
<div className="ml-6 shadow-hex-3e2c5a" style={{ width: 'calc(100% - 12rem)' }}>
|
|
|
- {allStaffList.length ? (
|
|
|
+ {state.params.departmentId && (
|
|
|
<BasicTable
|
|
|
rowKey="id"
|
|
|
- actionRef={tRef}
|
|
|
columns={columns}
|
|
|
- dataSource={dataSource}
|
|
|
params={state.params}
|
|
|
search={false}
|
|
|
+ request={async params => {
|
|
|
+ const {
|
|
|
+ code = -1,
|
|
|
+ data: { list = [], birthdayMonth = [], birthdayDay = [], total = 0 } = {
|
|
|
+ list: [],
|
|
|
+ birthdayMonth: [],
|
|
|
+ birthdayDay: [],
|
|
|
+ total: 0
|
|
|
+ }
|
|
|
+ } = await queryStaffContacts({ ...params })
|
|
|
+ setState({ ...state, birthdayMonth: birthdayMonth, birthdayDay: birthdayDay })
|
|
|
+ return {
|
|
|
+ data: list,
|
|
|
+ success: code === consts.RET_CODE.SUCCESS,
|
|
|
+ total
|
|
|
+ }
|
|
|
+ }}
|
|
|
toolbar={{
|
|
|
multipleLine: true,
|
|
|
search: (
|
|
|
<Input.Search
|
|
|
style={{ width: '280px' }}
|
|
|
allowClear={true}
|
|
|
- placeholder="请输入员工名称或手机进行搜索"
|
|
|
+ placeholder="请输入员工名称"
|
|
|
onSearch={handleSearch}
|
|
|
/>
|
|
|
),
|
|
|
filter: (
|
|
|
<div>
|
|
|
筛选:
|
|
|
- {character?.map(item => {
|
|
|
- return (
|
|
|
- <span className="inline-flex mb-1" key={item.id}>
|
|
|
- <Tag>{item.name}</Tag>
|
|
|
- </span>
|
|
|
- )
|
|
|
- })}
|
|
|
+ <Radio.Group
|
|
|
+ defaultValue="0"
|
|
|
+ options={character}
|
|
|
+ buttonStyle="solid"
|
|
|
+ optionType="button"
|
|
|
+ size="small"
|
|
|
+ onChange={onChangeHandle}
|
|
|
+ value={state.radioValue}
|
|
|
+ />
|
|
|
</div>
|
|
|
),
|
|
|
actions: [
|
|
|
<Space key="id">
|
|
|
- <Tag>
|
|
|
- 本月寿星:
|
|
|
- <Popover content={content} title={'本月寿星:'} trigger="click" placement="bottomLeft">
|
|
|
- <span>
|
|
|
- {character?.map(item => {
|
|
|
- return (
|
|
|
- <span style={{ marginLeft: -2 }} key={item.id}>
|
|
|
- {item.name}
|
|
|
- </span>
|
|
|
- )
|
|
|
- })}
|
|
|
- </span>
|
|
|
- </Popover>
|
|
|
- </Tag>
|
|
|
- <Tag>
|
|
|
- 本日:
|
|
|
- <Popover content={content} title={'本日寿星:'} trigger="click" placement="bottomLeft">
|
|
|
- AAA
|
|
|
- </Popover>
|
|
|
- </Tag>
|
|
|
+ {state.birthdayMonth.length ? (
|
|
|
+ <Tag>
|
|
|
+ <Popover
|
|
|
+ onClick={() => {
|
|
|
+ setState({ ...state, type: 'birthdayMonth' })
|
|
|
+ }}
|
|
|
+ content={content}
|
|
|
+ title={'本月寿星:'}
|
|
|
+ trigger="click"
|
|
|
+ placement="bottomLeft">
|
|
|
+ <div className="flex items-center cursor-pointer">
|
|
|
+ 本月寿星:
|
|
|
+ {state.birthdayMonth?.map(item => {
|
|
|
+ return (
|
|
|
+ <span
|
|
|
+ className="rounded-1/2 inline-block w-4 h-4"
|
|
|
+ style={{
|
|
|
+ marginLeft: -5,
|
|
|
+ backgroundImage: `url(${
|
|
|
+ (isDevMode() ? 'http://cld2qa.com' : window.location.origin) +
|
|
|
+ (item.avatar ?? consts.DEFAULT_AVATAR)
|
|
|
+ })`,
|
|
|
+ backgroundSize: 'cover'
|
|
|
+ }}
|
|
|
+ key={item.id}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </Popover>
|
|
|
+ </Tag>
|
|
|
+ ) : null}
|
|
|
+ {state.birthdayDay.length ? (
|
|
|
+ <Tag>
|
|
|
+ <Popover
|
|
|
+ onClick={() => {
|
|
|
+ setState({ ...state, type: 'birthdayDay' })
|
|
|
+ }}
|
|
|
+ content={content}
|
|
|
+ title={'本日寿星:'}
|
|
|
+ trigger="click"
|
|
|
+ placement="bottomLeft">
|
|
|
+ <div className="flex items-center cursor-pointer">
|
|
|
+ 本日:
|
|
|
+ {state.birthdayDay?.map(item => {
|
|
|
+ return (
|
|
|
+ <span
|
|
|
+ className="rounded-1/2 inline-block w-4 h-4"
|
|
|
+ style={{
|
|
|
+ marginLeft: -5,
|
|
|
+ backgroundImage: `url(${
|
|
|
+ (isDevMode() ? 'http://cld2qa.com' : window.location.origin) +
|
|
|
+ (item.avatar ?? consts.DEFAULT_AVATAR)
|
|
|
+ })`,
|
|
|
+ backgroundSize: 'cover'
|
|
|
+ }}
|
|
|
+ key={item.id}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </Popover>
|
|
|
+ </Tag>
|
|
|
+ ) : null}
|
|
|
</Space>
|
|
|
- ],
|
|
|
- settings: []
|
|
|
+ ]
|
|
|
}}
|
|
|
/>
|
|
|
- ) : null}
|
|
|
+ )}
|
|
|
</div>
|
|
|
</div>
|
|
|
</PageContainer>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-export default connect(({ staff }) => ({
|
|
|
- allStaffList: staff.allStaffList
|
|
|
-}))(Contacts)
|
|
|
+export default Contacts
|