|
@@ -1,942 +0,0 @@
|
|
|
-/*
|
|
|
- * @Author: code4eat awesomedema@gmail.com
|
|
|
- * @Date: 2023-03-03 11:30:33
|
|
|
- * @LastEditors: code4eat awesomedema@gmail.com
|
|
|
- * @LastEditTime: 2024-10-29 14:29:21
|
|
|
- * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
|
|
|
- * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
- */
|
|
|
-
|
|
|
-import { createFromIconfontCN } from '@ant-design/icons';
|
|
|
-
|
|
|
-import { DatePicker, Input, Modal, message, Table, Button, Popconfirm } from 'antd';
|
|
|
-import { useEffect, useRef, useState } from 'react';
|
|
|
-
|
|
|
-import { calculateReq, cancelAllocation, cancelIncomeCollection, downloadTemplateReq, generateReportHandle, getAfterCostShareSearchTableData, getAfterIncomeCollectionTableData, getCalcPageTableData, startAllocation, startIncomeCollection } from './service';
|
|
|
-
|
|
|
-import './style.less';
|
|
|
-import moment from 'moment';
|
|
|
-import 'moment/locale/zh-cn';
|
|
|
-import locale from 'antd/es/date-picker/locale/zh_CN';
|
|
|
-import KCIMPagecontainer from '@/components/KCIMPageContainer';
|
|
|
-import { KCIMTable } from '@/components/KCIMTable';
|
|
|
-
|
|
|
-import { ActionType, ProColumns, ProFormCascader, ProFormSelect } from '@ant-design/pro-components';
|
|
|
-import { formatMoneyNumber, formatToPercentage } from '@/utils/format';
|
|
|
-
|
|
|
-
|
|
|
-import { afterCollectionSearch, afterCostShareSearch, beforeCollectionSearch, beforeCostShareSearch, chargeItemCostCalc, clinicalPathway, costShare, costShareReportTable, departmentCostCalculate, departmentOperatingReport, diseaseCostCalculation, DRG_DIPCostCalc, incomeCollection, medicalMaterialCostCalc, medicalOrderItem, patientCostCalc, projectShareParamsCalc, unitPersonnelCostCalc, wholeHospCostCalculate, wholeHospOperatingReport } from './columns';
|
|
|
-import { afterCollectionSearchFilterConf, afterCostShareSearchFilterConf, beforeCollectionSearchFilterConf, beforeCostShareSearchFilterConf, chargeItemCostCalcFilterConf, clinicalPathwayFilterConf, departmentCostCalculateFilterConf, diseaseCostCalculationFilterConf, DRG_DIPCostCalcFilterConf, medicalMaterialCostCalcFilterConf, medicalOrderItemFilterConf, patientCostCalcFilterConf, PatientItemCalcFilterConf, patientStandItemCostCalcFilterConf, projectCostCalcFilterConf, projectShareParamsCalcFilterConf, standardItemCostCalcFilterConf, standItemShareCostCalcFilterConf, unitPersonnelCostCalcFilterConf } from './config';
|
|
|
-
|
|
|
-import ProgressModal from '@/components/ProgressModal';
|
|
|
-
|
|
|
-import ExportProgressModal from '@/pages/reportExport/report/ExportProgressModal';
|
|
|
-import exportTableToExcel from '@/utils/tableToExcel';
|
|
|
-
|
|
|
-import { useAccess, useParams } from '@umijs/max'
|
|
|
-import { useModel } from '@umijs/max';
|
|
|
-import { getParamsDataBySysId } from '@/services/getDic';
|
|
|
-
|
|
|
-
|
|
|
-const IconFont = createFromIconfontCN({
|
|
|
- scriptUrl: '',
|
|
|
-});
|
|
|
-
|
|
|
-const calTypeStr = `ITEM_COST_CALCULATE${(new Date()).getTime()}`;
|
|
|
-
|
|
|
-let currentPage = 0;
|
|
|
-let totalTableData: any[] = [];
|
|
|
-
|
|
|
-
|
|
|
-function transformChildToChildren(data: any[]) {
|
|
|
- return data.map(item => {
|
|
|
- let newItem = { ...item };
|
|
|
-
|
|
|
- // 如果有子项,将 'child' 属性改为 'children'
|
|
|
- if (newItem.child) {
|
|
|
- newItem.children = transformChildToChildren(newItem.child);
|
|
|
- delete newItem.child; // 删除原始的 'child' 属性
|
|
|
- }
|
|
|
-
|
|
|
- return newItem;
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-const getNextUnexpandedKeys = (data: any[], expandedKeys: any[] = []) => {
|
|
|
- let keys: any[] = [];
|
|
|
-
|
|
|
- const traverse = (nodes: any) => {
|
|
|
- for (const node of nodes) {
|
|
|
- // 如果当前节点还没有展开,就把它加入 keys
|
|
|
- if (!expandedKeys.includes(node.id)) {
|
|
|
- keys.push(node.id);
|
|
|
- }
|
|
|
-
|
|
|
- // 如果当前节点已经展开,继续遍历子节点
|
|
|
- if (node.children && expandedKeys.includes(node.id)) {
|
|
|
- traverse(node.children);
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- traverse(data);
|
|
|
-
|
|
|
- return keys;
|
|
|
-};
|
|
|
-
|
|
|
-export default function calcPageTemplate() {
|
|
|
- const { initialState, setInitialState } = useModel('@@initialState');
|
|
|
- const [computeDate, set_computeDate] = useState<string>(initialState ? initialState.computeDate : '');
|
|
|
- const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate });
|
|
|
- const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
|
|
|
- const tableRef = useRef<ActionType>();
|
|
|
- const [loading, set_loading] = useState(false);
|
|
|
- const params = useParams();
|
|
|
- const [columns, set_columns] = useState<ProColumns[]>([]);
|
|
|
- const [filterConf, set_filterConf] = useState<any[]>([]);
|
|
|
- const [scrollX, set_scrollX] = useState(500);
|
|
|
- const [ifShowCalcBtn, set_ifShowCalcBtn] = useState(true);
|
|
|
- const [totalCount, set_totalCount] = useState<undefined | number>(undefined);
|
|
|
- const [inputValues, setInputValues] = useState<{ [key: string]: any }>({});
|
|
|
- const [btnAccessStr, set_btnAccessStr] = useState<undefined | string>(undefined);
|
|
|
-
|
|
|
- const access = useAccess();
|
|
|
-
|
|
|
- const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
- const [openProcessModal, set_openProcessModal] = useState(false);
|
|
|
- const [allParentsKeys, set_allParentsKeys] = useState<any[]>([]);
|
|
|
- const [dataSource, set_dataSource] = useState<any[]>([]);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- const getTableData = async (params: any) => {
|
|
|
-
|
|
|
- const resp = await getCalcPageTableData({ ...params, ...tableDataFilterParams });
|
|
|
- if (resp) {
|
|
|
- try {
|
|
|
- if (params.calcPageKey == 'projectShareParamsCalc' || params.calcPageKey == 'projectCostCalc' || params.calcPageKey == 'patientItemCalc' || params.calcPageKey == 'standardItemCostCalc' || params.calcPageKey == 'patientStandItemCostCalc' || params.calcPageKey == 'standItemShareCostCalc') {
|
|
|
- const { pageData: { list = [], pageSize, totalCount, totalPage }, title } = resp;
|
|
|
- const columns: ProColumns[] = title.map((item: any, index: number) => {
|
|
|
- return {
|
|
|
- title: item.name,
|
|
|
- dataIndex: `${item.code}`,
|
|
|
- key: `${item.code}`,
|
|
|
- // width: getStringWidth(item.name, '14px'),
|
|
|
- ellipsis: true,
|
|
|
- fixed: item.freeze ? true : false,
|
|
|
- hideInTable: item.hide,
|
|
|
- align: item.dataType == 3 ? 'right' : 'left',
|
|
|
- sorter: item.sortStatus ? (a: any, b: any) => {
|
|
|
- if (item.dataType == 3) {
|
|
|
- //数值
|
|
|
- return b[`${item.code}`] - (a[`${item.code}`]);
|
|
|
- } else {
|
|
|
- return b[`${item.code}`]?.localeCompare(a[`${item.code}`]);
|
|
|
- }
|
|
|
- } : undefined,
|
|
|
- }
|
|
|
- });
|
|
|
- set_columns([...columns]);
|
|
|
-
|
|
|
- const data = list.map((item: any) => {
|
|
|
-
|
|
|
- let rowData: { [key: string]: any } = {};
|
|
|
-
|
|
|
- item.forEach((b: any) => {
|
|
|
- const needTitle = title.filter((a: any) => a.code == b.code);
|
|
|
- if (needTitle.length > 0) {
|
|
|
- rowData[`${needTitle[0].code}`] = b.value
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
- return { ...item, ...rowData, id: Math.random(), columns }
|
|
|
- });
|
|
|
-
|
|
|
- return {
|
|
|
- data: data,
|
|
|
- success: true,
|
|
|
- total: totalCount,
|
|
|
- pageSize: pageSize,
|
|
|
- totalPage: totalPage,
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- let data = (resp.list && resp.list != null) ? resp.list : (Array.isArray(resp) ? resp : []);
|
|
|
- if (params.calcPageKey == 'unitPersonnelCostCalc') {
|
|
|
- data = data ? data.map((a: any) => ({ ...a, children: a.childList })) : []
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'wholeHospCostCalculate') {
|
|
|
- data = data ? transformChildToChildren(data) : [];
|
|
|
- set_dataSource(data);
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'beforeCollectionSearch' || params.calcPageKey == 'beforeCostShareSearch' || params.calcPageKey == 'afterCostShareSearch' || params.calcPageKey == 'afterCollectionSearch') {
|
|
|
- const { totalAmount = 0 } = resp;
|
|
|
- set_totalCount(totalAmount);
|
|
|
- } else {
|
|
|
- set_totalCount(undefined);
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- data,
|
|
|
- success: true,
|
|
|
- total: resp.totalCount,
|
|
|
- pageSize: resp.pageSize,
|
|
|
- totalPage: resp.totalPage,
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- } catch (err) {
|
|
|
- console.log({ err })
|
|
|
- }
|
|
|
- }
|
|
|
- return [];
|
|
|
- };
|
|
|
-
|
|
|
- const tableDataSearchHandle = (paramName: string) => {
|
|
|
-
|
|
|
- set_tableDataFilterParams({
|
|
|
- ...tableDataFilterParams,
|
|
|
- [`${paramName}`]: inputValues[`${paramName}`]
|
|
|
- })
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const calcFunc = () => {
|
|
|
-
|
|
|
- Modal.confirm({
|
|
|
- title: '注意',
|
|
|
- content: '计算操作会覆盖当月已计算的数据,是否继续操作?',
|
|
|
- okText: '确定',
|
|
|
- cancelText: '取消',
|
|
|
- onOk: async (...args) => {
|
|
|
-
|
|
|
- if (params.calcPageKey != 'chargeItemCostCalc') {
|
|
|
- set_loading(true);
|
|
|
- const resp = await calculateReq(computeDate, params.calcPageKey);
|
|
|
- if (resp) {
|
|
|
- set_loading(false);
|
|
|
- message.success('操作成功!');
|
|
|
- tableRef.current?.reload();
|
|
|
- } else {
|
|
|
- set_loading(false);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if (params.calcPageKey == 'chargeItemCostCalc') {
|
|
|
- a();
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- },
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const a = async () => {
|
|
|
- setIsModalVisible(true);
|
|
|
- const resp = await calculateReq(computeDate, params.calcPageKey, calTypeStr);
|
|
|
-
|
|
|
- if (resp) {
|
|
|
- setIsModalVisible(false);
|
|
|
- } else {
|
|
|
- setIsModalVisible(false);
|
|
|
- }
|
|
|
- tableRef.current?.reload();
|
|
|
- }
|
|
|
-
|
|
|
- const generateFilterItems = (configs: any[]) => {
|
|
|
- const nodes = configs.map((item: any) => {
|
|
|
- const { type, key, label, placeholder, request } = item;
|
|
|
- if (type == 'input') {
|
|
|
- return (
|
|
|
- <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
|
|
|
- <span className='label' style={{ whiteSpace: 'nowrap' }}>{label}</span>
|
|
|
- <Input placeholder={`${placeholder}`} allowClear autoComplete='off'
|
|
|
- suffix={
|
|
|
- <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle(`${key}`)} />
|
|
|
- }
|
|
|
- value={inputValues[`${key}`] || ''}
|
|
|
- onChange={(e) => {
|
|
|
- setInputValues(prevValues => ({
|
|
|
- ...prevValues,
|
|
|
- [key]: e.target.value
|
|
|
- }));
|
|
|
- if (e.target.value.length == 0) {
|
|
|
- set_tableDataFilterParams({
|
|
|
- ...tableDataFilterParams,
|
|
|
- [`${key}`]: ''
|
|
|
- });
|
|
|
- }
|
|
|
- }}
|
|
|
-
|
|
|
- onPressEnter={(e) => {
|
|
|
- set_tableDataFilterParams({
|
|
|
- ...tableDataFilterParams,
|
|
|
- [`${key}`]: ((e.target) as HTMLInputElement).value
|
|
|
- });
|
|
|
- }}
|
|
|
-
|
|
|
- />
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
- if (type == 'select') {
|
|
|
-
|
|
|
- return (
|
|
|
- <div className='filterItem' style={{ marginLeft: 16 }}>
|
|
|
- <span className='label'>{label}</span>
|
|
|
- <ProFormSelect
|
|
|
- noStyle
|
|
|
- allowClear
|
|
|
- placeholder="请选择"
|
|
|
- style={{ width: 160, marginRight: 16 }}
|
|
|
- request={async () => {
|
|
|
- const arr = await request();
|
|
|
- if (arr) return arr
|
|
|
- return [];
|
|
|
- }}
|
|
|
-
|
|
|
- fieldProps={{
|
|
|
- onChange(value, option) {
|
|
|
- set_tableDataFilterParams({ ...tableDataFilterParams, [`${key}`]: value })
|
|
|
- },
|
|
|
-
|
|
|
- }}
|
|
|
- />
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
- if (type == 'cascader') {
|
|
|
-
|
|
|
- return (
|
|
|
- <div className='filterItem' style={{ marginLeft: 16 }}>
|
|
|
- <span className='label'>{label}</span>
|
|
|
- <ProFormCascader
|
|
|
- noStyle
|
|
|
- allowClear
|
|
|
-
|
|
|
- placeholder="请选择"
|
|
|
- request={async () => {
|
|
|
- const resp = await request();
|
|
|
- if (resp) {
|
|
|
- return resp
|
|
|
- }
|
|
|
- return [];
|
|
|
- }}
|
|
|
- fieldProps={{
|
|
|
- showSearch: true,
|
|
|
- fieldNames: { label: 'responsibilityName', value: 'responsibilityCode', children: 'child' },
|
|
|
- onChange(value: any, option: any) {
|
|
|
- set_tableDataFilterParams({ ...tableDataFilterParams, [`${key}`]: value ? value[value.length - 1] : null })
|
|
|
- },
|
|
|
- }}
|
|
|
- />
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
- return <></>
|
|
|
- });
|
|
|
-
|
|
|
- return nodes;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- const optionBtnGroupshandle = async (isCollection: boolean, record: any) => {
|
|
|
-
|
|
|
- if (params.calcPageKey == 'incomeCollection') {
|
|
|
- const { year, month } = record;
|
|
|
- if (isCollection) {
|
|
|
- const resp = await cancelIncomeCollection({ year, month });
|
|
|
- if (resp) {
|
|
|
- message.success('操作成功!');
|
|
|
- tableRef.current?.reload();
|
|
|
- }
|
|
|
- } else {
|
|
|
- Modal.confirm({
|
|
|
- title: '注意',
|
|
|
- content: '收入归集操作会覆盖已有的归集后数据,确定要继续操作?',
|
|
|
- okText: '确定',
|
|
|
- cancelText: '取消',
|
|
|
- onOk: async (...args) => {
|
|
|
- set_loading(true);
|
|
|
- const resp = await startIncomeCollection({ year, month });
|
|
|
- if (resp) {
|
|
|
-
|
|
|
- set_loading(false);
|
|
|
- message.success('操作成功!');
|
|
|
- tableRef?.current?.reload();
|
|
|
- } else {
|
|
|
- set_loading(false);
|
|
|
- }
|
|
|
- },
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'costShare') {
|
|
|
- const { year, month } = record;
|
|
|
- if (!isCollection) {
|
|
|
- //开始分摊
|
|
|
- Modal.confirm({
|
|
|
- title: '注意',
|
|
|
- content: '成本分摊操作会覆盖已有的分摊后数据,确定要继续操作?',
|
|
|
- okText: '确定',
|
|
|
- cancelText: '取消',
|
|
|
- onOk: async (...args) => {
|
|
|
- set_loading(true);
|
|
|
- const resp = await startAllocation({ year, month });
|
|
|
- if (resp) {
|
|
|
-
|
|
|
- set_loading(false);
|
|
|
- message.success('操作成功!');
|
|
|
- tableRef?.current?.reload();
|
|
|
- } else {
|
|
|
- set_loading(false);
|
|
|
- }
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
- }
|
|
|
- if (isCollection) {
|
|
|
- //撤销分摊
|
|
|
- const resp = await cancelAllocation({ year, month });
|
|
|
- if (resp) message.success('操作成功!');
|
|
|
- tableRef?.current?.reload();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- const openDataTable = async () => {
|
|
|
- set_loading(true);
|
|
|
- try {
|
|
|
- const { responsibilityCode = null } = tableDataFilterParams;
|
|
|
- let resp: any = undefined;
|
|
|
- if (params.calcPageKey == 'afterCostShareSearch') {
|
|
|
- resp = await getAfterCostShareSearchTableData(
|
|
|
- { year: `${computeDate}-01`, responsibilityCode }
|
|
|
- );
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'afterCollectionSearch') {
|
|
|
- resp = await getAfterIncomeCollectionTableData(
|
|
|
- { ...params, date: `${computeDate.replace(/-/g, '')}` }
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- if (resp) {
|
|
|
- const { titleMap = {}, realData = [], totalMap = {} } = resp;
|
|
|
- const titleMapToArr = Object.entries(titleMap);
|
|
|
- const totalMapToArr = Object.entries(totalMap);
|
|
|
- const columns = [...titleMapToArr].map((item, index) => {
|
|
|
- if (index == 0 || index == [...titleMapToArr].length - 1) {
|
|
|
- return {
|
|
|
- title: item[1],
|
|
|
- key: item[0],
|
|
|
- dataIndex: item[0],
|
|
|
- fixed: index == 0 ? 'left' : 'right',
|
|
|
- width: 150,
|
|
|
- }
|
|
|
- }
|
|
|
- return {
|
|
|
- title: item[1],
|
|
|
- dataIndex: item[0],
|
|
|
- key: item[0],
|
|
|
- width: 150,
|
|
|
- }
|
|
|
- });
|
|
|
- set_loading(false);
|
|
|
- Modal.info({
|
|
|
- title: '报表数据',
|
|
|
- icon: '',
|
|
|
- okText: '确定',
|
|
|
- width: 800,
|
|
|
- content: (
|
|
|
- <KCIMTable
|
|
|
- rowKey='id'
|
|
|
- scroll={{ x: (columns.length) * 150, y: 450 }}
|
|
|
- columns={columns as ProColumns[]}
|
|
|
- dataSource={[...realData]}
|
|
|
- pagination={false}
|
|
|
- summary={() => (
|
|
|
- <Table.Summary fixed >
|
|
|
- <Table.Summary.Row className="rowCell">
|
|
|
- {/* <Table.Summary.Cell className="firstCell" index={0}>合计</Table.Summary.Cell> */}
|
|
|
- {
|
|
|
- totalMapToArr.map((item, index) => {
|
|
|
- return (
|
|
|
- <Table.Summary.Cell key={index} className={index == totalMapToArr.length - 1 ? 'ant-table-cell ant-table-cell-fix-right ant-table-cell-fix-right-last' : 'cell'} index={index}>{item[1] as any}</Table.Summary.Cell>
|
|
|
- )
|
|
|
- })
|
|
|
- }
|
|
|
- </Table.Summary.Row>
|
|
|
- </Table.Summary>
|
|
|
- )}
|
|
|
- />
|
|
|
- )
|
|
|
- })
|
|
|
-
|
|
|
- }
|
|
|
- } catch (err) {
|
|
|
- console.log({ err });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const generateReport = async () => {
|
|
|
- // {date:computeDate,reportType:0}
|
|
|
- if (params.calcPageKey == 'departmentOperatingReport') {
|
|
|
- const resp = await generateReportHandle({ date: `${computeDate}-01`, reportType: 0 }, '/costAccount/costdepartmentprofit/getDepartProfitReport');
|
|
|
- if (resp) {
|
|
|
- tableRef.current?.reload();
|
|
|
- }
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'wholeHospOperatingReport') {
|
|
|
- const resp = await generateReportHandle({ date: `${computeDate}-01`, reportType: 0 }, '/costAccount/hospProfitAndLoss/report');
|
|
|
- if (resp) {
|
|
|
- tableRef.current?.reload();
|
|
|
- }
|
|
|
- }
|
|
|
- if (params.calcPageKey == 'costShareReportTable') {
|
|
|
- const resp = await generateReportHandle({ date: `${computeDate}-01`, reportType: 0 }, '/costAccount/hospProfitAndLoss/report');
|
|
|
- if (resp) {
|
|
|
- tableRef.current?.reload();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const handleCompletion = () => {
|
|
|
- setIsModalVisible(false);
|
|
|
- };
|
|
|
-
|
|
|
- const handleExportCompletion = () => {
|
|
|
- currentPage = 0;
|
|
|
- set_openProcessModal(false);
|
|
|
- exportHandle(params.calcPageKey == 'wholeHospCostCalculate' ? 'reportName' : undefined);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- const exportHandle = (indentColumn?: string) => { // 将 indentColumn 设置为可选参数
|
|
|
- let headers: { [key: string]: any } = {};
|
|
|
- let data: any[] = [];
|
|
|
-
|
|
|
- // 生成表头
|
|
|
- columns.forEach(a => {
|
|
|
- headers[`${a.dataIndex}`] = a.title;
|
|
|
- });
|
|
|
-
|
|
|
- // 递归处理数据,支持嵌套的 children,并为指定列添加缩进
|
|
|
- const processData = (items: any[], level: number = 0) => {
|
|
|
- items.forEach(item => {
|
|
|
- let _temp: { [key: string]: any } = {};
|
|
|
-
|
|
|
- Object.keys(headers).forEach(key => {
|
|
|
- if (indentColumn && key === indentColumn) { // 检查是否需要缩进
|
|
|
- // 使用 Unicode 不可见空格来缩进
|
|
|
- _temp[`${key}`] = `${'\u00A0'.repeat(level * 4)}${item[`${key}`]}`; // 使用4个不可见空格字符缩进
|
|
|
- } else if (item.children && item.children.length > 0 && (params.calcPageKey != 'wholeHospCostCalculate')) {
|
|
|
- // 如果有 children,返回空字符串来保持 Excel 也为空
|
|
|
- _temp[`${key}`] = '';
|
|
|
- } else {
|
|
|
- if (params.calcPageKey == 'wholeHospCostCalculate') {
|
|
|
- if (key == 'amount') {
|
|
|
- _temp[`${key}`] = (item[`${key}`] != undefined||item[`${key}`] != null) ? formatMoneyNumber(item[`${key}`]) : item[`${key}`];
|
|
|
- }
|
|
|
- if (key == 'percent') {
|
|
|
- _temp[`${key}`] = (item[`${key}`] != undefined||item[`${key}`] != null) ? formatToPercentage(item[`${key}`]) : item[`${key}`];
|
|
|
- }
|
|
|
- } else {
|
|
|
- _temp[`${key}`] = item[`${key}`];
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- data.push(_temp);
|
|
|
-
|
|
|
- // 递归处理子项,增加缩进层级
|
|
|
- if (item.children && item.children.length > 0) {
|
|
|
- processData(item.children, level + 1);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- // 开始处理数据
|
|
|
- processData(totalTableData);
|
|
|
-
|
|
|
- // 导出数据到 Excel
|
|
|
- exportTableToExcel(data, columns as any[], params.calcPageKey == 'wholeHospCostCalculate' ? '全院损益报表' : '项目成本计算');
|
|
|
-
|
|
|
- // 清空当前页和总数据
|
|
|
- currentPage = 0;
|
|
|
- totalTableData = [];
|
|
|
- // tableRef.current?.reload();
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- const fetchExportData = async () => {
|
|
|
-
|
|
|
- currentPage = currentPage + 1;
|
|
|
-
|
|
|
- const resp: any = await getTableData({ ...tableDataFilterParams, current: currentPage, pageSize: 100 });
|
|
|
-
|
|
|
- if (resp) {
|
|
|
- const { total = 0, data } = resp;
|
|
|
- totalTableData = [...totalTableData, ...data];
|
|
|
- return {
|
|
|
- currentCount: totalTableData.length,
|
|
|
- totalCount: total,
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- return { currentCount: 0, totalCount: 0 };
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const handleExpandNext = () => {
|
|
|
- // 当前所有未展开的节点,第一层优先展开
|
|
|
- const keysToExpand = getNextUnexpandedKeys(dataSource, allParentsKeys);
|
|
|
- set_allParentsKeys((prev) => Array.from(new Set([...prev, ...keysToExpand])));
|
|
|
- };
|
|
|
-
|
|
|
- const handleCollapseAll = () => {
|
|
|
- set_allParentsKeys([]);
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- const getIfshowPercent = async ()=>{
|
|
|
- const {systemId} = JSON.parse(localStorage.getItem('currentSelectedTab') as string)
|
|
|
- const resp = await getParamsDataBySysId(systemId,'1851077044079824896');
|
|
|
- if(resp){
|
|
|
- return resp.value == '1'?true:false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- useEffect(() => {
|
|
|
- setInputValues({});
|
|
|
- const { calcPageKey } = params;
|
|
|
- if (calcPageKey == "chargeItemCostCalc") {
|
|
|
- set_columns(chargeItemCostCalc);
|
|
|
- set_filterConf(chargeItemCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1500);
|
|
|
- }
|
|
|
- if (calcPageKey == "standardItemCostCalc") {
|
|
|
-
|
|
|
- set_filterConf(standardItemCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1500);
|
|
|
- }
|
|
|
- if (calcPageKey == "patientStandItemCostCalc") {
|
|
|
-
|
|
|
- set_filterConf(patientStandItemCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1500);
|
|
|
- }
|
|
|
- if (calcPageKey == "standItemShareCostCalc") {
|
|
|
-
|
|
|
- set_filterConf(standItemShareCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1500);
|
|
|
- }
|
|
|
- if (calcPageKey == "patientItemCalc") {
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(PatientItemCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "patientCostCalc") {
|
|
|
- set_columns(patientCostCalc);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(patientCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "unitPersonnelCostCalc") {
|
|
|
- set_columns(unitPersonnelCostCalc);
|
|
|
- set_scrollX(1000);
|
|
|
- set_filterConf(unitPersonnelCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "diseaseCostCalculation") {
|
|
|
- set_columns(diseaseCostCalculation);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(diseaseCostCalculationFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "DRG_DIPCostCalc") {
|
|
|
- set_columns(DRG_DIPCostCalc);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(DRG_DIPCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "clinicalPathway") {
|
|
|
- set_columns(clinicalPathway);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(clinicalPathwayFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "medicalOrderItem") {
|
|
|
- set_columns(medicalOrderItem);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(medicalOrderItemFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "beforeCollectionSearch") {
|
|
|
- set_columns(beforeCollectionSearch);
|
|
|
- set_scrollX(1500);
|
|
|
- set_filterConf(beforeCollectionSearchFilterConf);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- }
|
|
|
- if (calcPageKey == "incomeCollection") {
|
|
|
- set_columns([...incomeCollection, {
|
|
|
- title: '操作',
|
|
|
- dataIndex: 'option',
|
|
|
- width: 90,
|
|
|
- renderText(text, record) {
|
|
|
- const { isCollection } = record;
|
|
|
- return <a style={{ fontSize: 14 }} onClick={() => {
|
|
|
- optionBtnGroupshandle(isCollection, record);
|
|
|
- }}>{isCollection ? '撤销归集' : '开始归集'}</a>
|
|
|
- },
|
|
|
- }]);
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- set_scrollX(600);
|
|
|
- }
|
|
|
- if (calcPageKey == "afterCollectionSearch") {
|
|
|
- set_columns([...afterCollectionSearch]);
|
|
|
- set_filterConf(afterCollectionSearchFilterConf);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- set_scrollX(1300);
|
|
|
- }
|
|
|
- if (calcPageKey == "beforeCostShareSearch") {
|
|
|
- set_columns([...beforeCostShareSearch]);
|
|
|
- set_filterConf(beforeCostShareSearchFilterConf);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- set_scrollX(1300);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (calcPageKey == "costShare") {
|
|
|
- set_columns([...costShare, {
|
|
|
- title: '操作',
|
|
|
- align: 'right',
|
|
|
- dataIndex: 'option',
|
|
|
- width: '15%',
|
|
|
- render: (_, record) => {
|
|
|
- const { isAllocation: isCollection } = record;
|
|
|
- return !isCollection?
|
|
|
- <a style={{ fontSize: 14 }} onClick={() => optionBtnGroupshandle(isCollection, record)}>{isCollection ? '撤销' : '分摊'}</a>
|
|
|
- :[
|
|
|
- <Popconfirm
|
|
|
- title={`是否确认撤销?`}
|
|
|
- key="del"
|
|
|
- onConfirm={() => optionBtnGroupshandle(isCollection, record)}
|
|
|
- >
|
|
|
- <a style={{ fontSize: 14 }}>{isCollection ? '撤销' : '分摊'}</a>
|
|
|
- </Popconfirm>
|
|
|
-
|
|
|
- ]
|
|
|
- },
|
|
|
- }]);
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- set_scrollX(600);
|
|
|
- }
|
|
|
- if (calcPageKey == "afterCostShareSearch") {
|
|
|
- set_columns([...afterCostShareSearch]);
|
|
|
- set_filterConf(afterCostShareSearchFilterConf);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- set_scrollX(1000);
|
|
|
- }
|
|
|
-
|
|
|
- if (calcPageKey == "medicalMaterialCostCalc") {
|
|
|
- set_columns([...medicalMaterialCostCalc]);
|
|
|
- set_filterConf(medicalMaterialCostCalcFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1200);
|
|
|
- }
|
|
|
-
|
|
|
- if (calcPageKey == "departmentCostCalculate") {
|
|
|
- set_columns([...departmentCostCalculate]);
|
|
|
- set_filterConf(departmentCostCalculateFilterConf);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- }
|
|
|
- if (calcPageKey == "wholeHospCostCalculate") {
|
|
|
- getIfshowPercent().then((resp)=>{
|
|
|
- set_columns(resp?[...wholeHospCostCalculate]:[...(wholeHospCostCalculate.filter(a=>a.title != '占比'))]);
|
|
|
- })
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- const tabs = access.whatCanIDoInThisPage(location.pathname.replace('/CostAccountingSys', ''));
|
|
|
- const a = tabs.reduce((prev: any, cur: any) => `${prev},${cur.code}`, '');
|
|
|
- set_btnAccessStr(a);
|
|
|
- }
|
|
|
- if (calcPageKey == "costShareReportTable") {
|
|
|
- set_columns([...costShareReportTable, {
|
|
|
- title: '操作',
|
|
|
- dataIndex: 'option',
|
|
|
- width: '15%',
|
|
|
- render: (_, record) => {
|
|
|
- const { year, month, shareLevel, shareLevelId } = record;
|
|
|
- return [
|
|
|
- <a style={{ fontSize: 14 }} onClick={async () => {
|
|
|
- downloadTemplateReq('/costAccount/excel/getShareReportTemplate', { year, month, levelSort: shareLevel, shareLevelId });
|
|
|
- //const resp = await downloadReportHandle({ year, month, levelSort:shareLevel, shareLevelId });
|
|
|
- }}>下载</a>
|
|
|
- ]
|
|
|
- },
|
|
|
- }]);
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- }
|
|
|
- if (calcPageKey == "departmentOperatingReport") {
|
|
|
- set_columns([...departmentOperatingReport, {
|
|
|
- title: '操作',
|
|
|
- dataIndex: 'option',
|
|
|
- width: 100,
|
|
|
- render: (_, record) => {
|
|
|
- const { fileUrl = '' } = record;
|
|
|
- return [
|
|
|
- <a style={{ fontSize: 14 }} onClick={async () => window.open(fileUrl)}>下载</a>
|
|
|
- ]
|
|
|
- },
|
|
|
- }]);
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- }
|
|
|
- if (calcPageKey == "wholeHospOperatingReport") {
|
|
|
- set_columns([...wholeHospOperatingReport, {
|
|
|
- title: '操作',
|
|
|
- dataIndex: 'option',
|
|
|
- width: 100,
|
|
|
- render: (_, record) => {
|
|
|
- const { fileUrl } = record;
|
|
|
- return [
|
|
|
- <a style={{ fontSize: 14 }} onClick={async () => {
|
|
|
- window.open(fileUrl);
|
|
|
- }}>下载</a>
|
|
|
- ]
|
|
|
- },
|
|
|
- }]);
|
|
|
- set_filterConf([]);
|
|
|
- set_ifShowCalcBtn(false);
|
|
|
- }
|
|
|
- if (calcPageKey == "projectShareParamsCalc") {
|
|
|
- set_filterConf([...projectShareParamsCalcFilterConf]);
|
|
|
- set_ifShowCalcBtn(true);
|
|
|
- set_scrollX(1600);
|
|
|
- set_totalCount(undefined);
|
|
|
- }
|
|
|
- if (calcPageKey == "projectCostCalc") {
|
|
|
-
|
|
|
- set_filterConf([...projectCostCalcFilterConf]);
|
|
|
-
|
|
|
- const tabs = access.whatCanIDoInThisPage(location.pathname.replace('/CostAccountingSys', ''));
|
|
|
- const a = tabs.reduce((prev: any, cur: any) => `${prev},${cur.code}`, '');
|
|
|
- set_btnAccessStr(a);
|
|
|
- set_ifShowCalcBtn(a.indexOf('calculate') != -1);
|
|
|
- set_scrollX(1200);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- set_tableDataFilterParams({ ...tableDataFilterParams, computeDate, calcPageKey, reportType: calcPageKey == 'wholeHospCostCalculate' ? 3 : tableDataFilterParams.reportType });
|
|
|
-
|
|
|
- }, [params]);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- return (
|
|
|
- <KCIMPagecontainer className="calcPageTemplate" title={false}>
|
|
|
- <ProgressModal
|
|
|
- title='计算进度'
|
|
|
- type={calTypeStr}
|
|
|
- onComplete={handleCompletion}
|
|
|
- visible={isModalVisible}
|
|
|
- />
|
|
|
- <ExportProgressModal
|
|
|
- visible={openProcessModal}
|
|
|
- onCancel={() => set_openProcessModal(false)}
|
|
|
- fetchData={fetchExportData}
|
|
|
- onCompletion={handleExportCompletion}
|
|
|
- />
|
|
|
- <div className="toolBar">
|
|
|
- <div className="filter">
|
|
|
- <div className="filterItem">
|
|
|
- {
|
|
|
- <div className="search">
|
|
|
- <span>核算年月:</span>
|
|
|
- <DatePicker
|
|
|
- onChange={(data, dateString) => {
|
|
|
- set_computeDate(dateString);
|
|
|
- setInitialState((s: any) => ({ ...s, computeDate: dateString }));
|
|
|
- set_tableDataFilterParams({
|
|
|
- ...tableDataFilterParams,
|
|
|
- computeDate: dateString,
|
|
|
- });
|
|
|
- }}
|
|
|
- picker="month"
|
|
|
- locale={locale}
|
|
|
- defaultValue={moment(computeDate, 'YYYY-MM')}
|
|
|
- format="YYYY-MM"
|
|
|
- autoComplete='off'
|
|
|
- placeholder="选择年月"
|
|
|
- />
|
|
|
- </div>
|
|
|
- }
|
|
|
- </div>
|
|
|
- {generateFilterItems(filterConf)}
|
|
|
- </div>
|
|
|
- <div className="btnGroup">
|
|
|
- {params.calcPageKey == 'wholeHospCostCalculate' && (
|
|
|
- <>
|
|
|
- <span className='btn' onClick={() => handleCollapseAll()}>全部折叠</span>
|
|
|
- <span className='btn' style={{ marginRight: 16 }} onClick={() => handleExpandNext()}>展开下一层</span>
|
|
|
- </>
|
|
|
- )}
|
|
|
- {((params.calcPageKey == 'projectCostCalc' || params.calcPageKey == 'wholeHospCostCalculate') && btnAccessStr ? (btnAccessStr.indexOf('export') != -1) : false) && <a className='export' onClick={() => set_openProcessModal(true)}>导出</a>}
|
|
|
- {ifShowCalcBtn && <a className='calc' onClick={() => calcFunc()}>计算</a>}
|
|
|
- {(params.calcPageKey == 'afterCostShareSearch' || params.calcPageKey == 'afterCollectionSearch') && (<Button loading={loading} size='small' className='reportDataBtn' onClick={() => openDataTable()}>报表数据</Button>)}
|
|
|
- {(params.calcPageKey == 'departmentOperatingReport' || params.calcPageKey == 'wholeHospOperatingReport') && (<span className='reportDataBtn' onClick={() => generateReport()}>生成报表</span>)}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div style={{ marginTop: 16 }}>
|
|
|
-
|
|
|
- <KCIMTable
|
|
|
- columns={columns}
|
|
|
- actionRef={tableRef}
|
|
|
- rowKey="id"
|
|
|
- expandable={params.calcPageKey == 'wholeHospCostCalculate' ? {
|
|
|
- defaultExpandAllRows: true, expandedRowKeys: allParentsKeys,
|
|
|
- onExpand(expanded, record) {
|
|
|
- const { id } = record;
|
|
|
- if (!expanded) {
|
|
|
- const expandedKeys = allParentsKeys.filter(a => a != id);
|
|
|
- set_allParentsKeys([...expandedKeys]);
|
|
|
- } else {
|
|
|
- set_allParentsKeys([...allParentsKeys, id]);
|
|
|
- }
|
|
|
- },
|
|
|
- } : undefined}
|
|
|
- rowClassName={params.calcPageKey == 'wholeHospCostCalculate' ? ((record) => (record.children ? 'has-children hover-row' : 'hover-row')) : ''}
|
|
|
- scroll={{ x: scrollX, y: params.calcPageKey == 'afterCostShareSearch' ? `calc(100vh - 270px)` : `calc(100vh - 233px)` }}
|
|
|
- params={tableDataFilterParams}
|
|
|
- request={(params) => getTableData(params)}
|
|
|
- pagination={params.calcPageKey == 'wholeHospCostCalculate' ? false : undefined}
|
|
|
- />
|
|
|
- {
|
|
|
- totalCount != undefined && <a style={{ marginTop: 16, display: 'inline-block' }}>{`合计:${formatMoneyNumber(totalCount)}`}</a>
|
|
|
- }
|
|
|
- </div>
|
|
|
- </KCIMPagecontainer>
|
|
|
- );
|
|
|
-}
|