| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- import { useState, useEffect, useRef, useMemo } from 'react'
- import BasicTable from '@/components/Table'
- import { DatePicker, Select, TreeSelect, Table, Typography } from 'antd'
- import { querySoftwareUsageList, queryUsageSelectOptions } from '@/services/statistic'
- import consts from '@/consts'
- import { useDebounceFn } from 'ahooks'
- import dayjs from 'dayjs'
- import { Pie } from '@ant-design/charts'
- import { isMobile } from '@/utils/is'
- const { Text } = Typography
- const opMap = {
- STAFF: 'staff',
- DEPARTMENT: 'department'
- }
- const colLabelValToZH = {
- giftsCount: '赠送',
- lendCount: '借出',
- salesCount: '销售'
- }
- const Usage = () => {
- const tRef = useRef(null)
- const [state, setState] = useState({
- optionType: opMap.STAFF,
- opIds: [],
- department: null,
- staff: null,
- startMonth: [dayjs(new Date()), dayjs(new Date())]
- })
- const queryStaffAndDepartment = async () => {
- const { code = -1, data: { department = [], staff = [] } = {} } =
- await queryUsageSelectOptions()
- if (code === consts.RET_CODE.SUCCESS) {
- setState({
- ...state,
- department,
- staff
- })
- tRef.current?.reload()
- }
- }
- const mainParams = useMemo(() => {
- const p = { optionType: state.optionType, startMonth: state.startMonth[0].format('YYYY-MM') }
- if (state.optionType === opMap.STAFF) {
- p.staffIds = state.opIds
- } else {
- p.departmentIds = state.opIds
- }
- return p
- }, [state.optionType, state.opIds, state.startMonth])
- const options = useMemo(() => {
- if (state.optionType === opMap.STAFF) {
- return state.staff?.map(item => ({ label: item.username, value: item.id })) || []
- }
- return state.department || []
- }, [state.optionType, state.staff, state.department])
- const pieData = useMemo(() => {
- if (!state.chart || !state.sum) return {}
- const leftKeys = Object.keys(state.chart)
- const pieLeft = []
- leftKeys.forEach(item => {
- const v = state.chart[item]
- pieLeft.push({ label: item === 'unused' ? '未使用' : '已使用', value: v })
- })
- const rightKeys = Object.keys(state.sum)
- const pieRight = []
- rightKeys.forEach(item => {
- const v = state.sum[item]
- if (item !== 'receiveCount') {
- pieRight.push({ label: colLabelValToZH[item], value: v })
- }
- })
- return { pieLeft, pieRight }
- }, [state.chart])
- useEffect(() => {
- queryStaffAndDepartment()
- }, [])
- const { run: trySetOpIds } = useDebounceFn(
- ids => {
- setState({ ...state, opIds: ids })
- },
- { wait: 500 }
- )
- useEffect(() => {
- // 发起请求
- if (state.opIds?.length) {
- tRef.current?.reload()
- }
- }, [state.opIds])
- const columns = [
- {
- title: '名称',
- dataIndex: 'name',
- key: 'name',
- width: 100,
- fixed: 'left',
- align: 'center'
- },
- {
- title: '未使用',
- children: [
- {
- title: '生成',
- key: 'create',
- dataIndex: 'create',
- align: 'center'
- },
- {
- title: '接收',
- key: 'receive',
- dataIndex: 'receive',
- align: 'center'
- }
- ]
- },
- {
- title: '已使用',
- children: [
- {
- title: '借出',
- key: 'lend',
- dataIndex: 'lend',
- align: 'center'
- },
- {
- title: '销售',
- key: 'sales',
- dataIndex: 'sales',
- align: 'center'
- },
- {
- title: '赠送',
- key: 'gifts',
- dataIndex: 'gifts',
- align: 'center'
- }
- ]
- }
- ]
- const leftConfig = {
- appendPadding: 10,
- data: pieData.pieLeft,
- angleField: 'value',
- colorField: 'label',
- radius: 0.9,
- color: ['#40B7E6', '#79CE67'],
- interactions: [{ type: 'element-active' }]
- }
- const rightConfig = {
- appendPadding: 10,
- data: pieData.pieRight,
- angleField: 'value',
- colorField: 'label',
- radius: 0.9,
- color: ['#40B7E6', '#79CE67', '#FBD743', '#FB7A53'],
- interactions: [{ type: 'element-active' }]
- }
- return (
- <div className="flex flex-col">
- {!isMobile() && (
- <div className="flex flex-row justify-between mb-4">
- <div className="card-transition w-1/2 bg-white mr-2">
- {pieData.pieLeft ? <Pie {...leftConfig} /> : null}
- </div>
- <div className="card-transition w-1/2 bg-white ml-2">
- {pieData.pieRight ? <Pie {...rightConfig} /> : null}
- </div>
- </div>
- )}
- <BasicTable
- manualRequest
- search={false}
- columns={columns}
- actionRef={tRef}
- rowkey="id"
- toolbar={{
- title: [
- <Select
- key="Select"
- defaultValue="staff"
- options={[
- { label: '部门', value: 'department' },
- { label: '员工', value: 'staff' }
- ]}
- onChange={val => setState({ ...state, optionType: val })}
- />,
- state.optionType === opMap.STAFF ? (
- <Select
- key="StaffSelect"
- className="min-w-120px"
- defaultOpen
- dropdownMatchSelectWidth
- options={options}
- mode="multiple"
- onChange={value => trySetOpIds(value)}
- />
- ) : (
- <TreeSelect
- key="DepartmentSelect"
- defaultOpen
- treeData={options}
- className="min-w-120px"
- dropdownMatchSelectWidth
- multiple
- onChange={value => trySetOpIds(value)}
- />
- )
- ],
- actions: [
- <DatePicker.RangePicker
- picker="month"
- key="DatePicker"
- disabled={[false, true]}
- value={state.startMonth}
- onChange={val => setState({ ...state, startMonth: val })}
- />
- ]
- }}
- params={mainParams}
- pagination={false}
- bordered
- request={async (params, sort, filter) => {
- const {
- code = -1,
- data: { list, sum, chart, create }
- } = await querySoftwareUsageList({ ...params, ...sort, ...filter })
- setState({ ...state, sum, chart, create })
- return {
- data: list,
- success: code === consts.RET_CODE.SUCCESS,
- total: list?.length || 0
- }
- }}
- summary={data =>
- data?.length ? (
- <>
- <Table.Summary.Row>
- <Table.Summary.Cell className="text-center">小计</Table.Summary.Cell>
- <Table.Summary.Cell className="text-center">{state.create}</Table.Summary.Cell>
- <Table.Summary.Cell className="text-center">
- {state.sum?.receiveCount}
- </Table.Summary.Cell>
- <Table.Summary.Cell className="text-center">
- {state.sum?.lendCount}
- </Table.Summary.Cell>
- <Table.Summary.Cell className="text-center">
- {state.sum?.salesCount}
- </Table.Summary.Cell>
- <Table.Summary.Cell className="text-center">
- {state.sum?.giftsCount}
- </Table.Summary.Cell>
- </Table.Summary.Row>
- <Table.Summary.Row>
- <Table.Summary.Cell className="text-center">总计</Table.Summary.Cell>
- <Table.Summary.Cell colSpan={2} className="text-center">
- <Text type="danger">{state.create + state.sum?.receiveCount}</Text>
- </Table.Summary.Cell>
- <Table.Summary.Cell colSpan={3} className="text-center">
- <Text type="danger">
- {state.sum?.lendCount + state.sum?.salesCount + state.sum?.giftsCount}
- </Text>
- </Table.Summary.Cell>
- </Table.Summary.Row>
- </>
- ) : null
- }
- />
- </div>
- )
- }
- export default Usage
|