123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 |
- /*
- * @Author: code4eat awesomedema@gmail.com
- * @Date: 2023-03-03 11:30:33
- * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2025-05-12 14:59:43
- * @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 KCIMPagecontainer from '@/components/KCIMPageContainer';
- import { KCIMTable } from '@/components/KCIMTable';
- import { createFromIconfontCN } from '@ant-design/icons';
- import { ActionType, ProFormDependency, ProFormInstance, ProFormText, ProFormSelect, ProFormDigit, ProFormRadio } from '@ant-design/pro-components';
- import { ModalForm, ProFormTextArea } from '@ant-design/pro-form'
- import { ProColumns } from '@ant-design/pro-table';
- import { Modal, message, Popconfirm, Form, Tabs, Switch, Row, Col } from 'antd';
- import { Key, useEffect, useRef, useState } from 'react';
- import 'moment/locale/zh-cn';
- import locale from 'antd/es/date-picker/locale/zh_CN';
- import { addData, copyDataToSelectedType, delData, editData, getReportProjectSettingList, saveReportRelation } from './service';
- import './style.less';
- import TableTransfer from './transform';
- import React from 'react';
- import { cleanTree } from '@/utils/tooljs';
- import { getDicDataBySysId } from '@/services/getDic';
- const IconFont = createFromIconfontCN({
- scriptUrl: '',
- });
- let currentRow: any = undefined;
- const accountingSubjectColumn = [
- {
- title: '会计科目编码',
- dataIndex: 'accountingCode',
- ellipsis: true,
- },
- {
- title: '会计科目名',
- dataIndex: 'accountingName',
- ellipsis: true,
- },
- ];
- const shareParamsColumn = [
- {
- title: '分摊层级Id',
- dataIndex: 'id',
- ellipsis: true,
- },
- {
- title: '分摊层级名',
- dataIndex: 'shareName',
- ellipsis: true,
- },
- ];
- const responsibilityColumn = [
- {
- title: '责任中心编码',
- dataIndex: 'responsibilityCode',
- ellipsis: true,
- },
- {
- title: '责任中心名',
- dataIndex: 'responsibilityName',
- ellipsis: true,
- },
- ];
- const openRule = () => {
- Modal.info({
- title: '报表项目填写注意事项!',
- width: 800,
- content: (
- <div>
- <h4>计算类型说明 </h4>
- <span>不设置:</span>
- 一般用于第一层。 对应成本科目:对应的是成本科目,如工资,收入类等
- <div></div>
- <span>对应责任中心:</span>
- 对应的是分摊的责任中心,放射科,功能科等
- <div></div>
- <span>对应分摊层级:</span>
- 对应的是分摊的层级,如"护理"分摊层级,"医技"分摊层级。
- <div></div>
- <span>小计:</span>
- 是对第一层下的所有项目的合计计算。
- <div></div>
- <span>计算公式:</span>
- 是按编号对报表项目的项目进行计算结果,支持加/减法。
- <div style={{ marginBottom: 20 }}></div>
- <h4>报表项目顺序注意事项</h4>
- 计算类型是小计报表项目需要维护在对应层级的其他项目之后
- <div></div>
- 计算类型是计算公式的报表项目需要维护在公式里包含的其他项目之后
- </div>
- ),
- });
- };
- export default function ReportItemSet() {
- const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>({ reportType: 0 });
- const tableRef = useRef<ActionType>();
- const formRef = useRef<ProFormInstance>();
- const [tabs, set_tabs] = useState<any[]>([]);
- const [reportType, set_reportType] = useState<Key | undefined>(undefined);
- const [calcTypes, setCalcTypes] = useState<any[]>([]);
- const columns: ProColumns[] = [
- {
- title: '报表项目名',
- dataIndex: 'reportName',
- width: 200
- },
- {
- title: 'Id',
- dataIndex: 'id',
- width: 80
- },
- {
- title: '编号',
- dataIndex: 'num',
- width: 80
- },
- {
- title: '计算方式',
- dataIndex: 'calcType',
- renderText: (num, record) => {
- const temp = calcTypes.filter((a) => a.code == num);
- return temp.length > 0 ? temp[0].name : ''
- },
- },
- // {
- // title: '报表类型',
- // dataIndex: 'reportType',
- // renderText(num) {
- // switch (num) {
- // case 0:
- // return <>损益表</>;
- // case 1:
- // return <>完全成本法表</>;
- // case 2:
- // return <>变动成本表</>;
- // case 3:
- // return <>全院损益表</>;
- // case 4:
- // return <>全成本报表</>;
- // }
- // },
- // },
- {
- title: '计算公式',
- width: 300,
- dataIndex: 'calcFormula',
- },
- {
- title: '项目类型',
- dataIndex: 'costType',
- renderText(num) {
- switch (num) {
- case 1:
- return <>收入</>;
- case 2:
- return <>成本</>;
- }
- },
- },
- {
- title: '占比计算类型',
- dataIndex: 'fraction',
- renderText(num) {
- switch (num) {
- case 1:
- return <>分子</>;
- case 2:
- return <>分母</>;
- case 3:
- return <>不计算</>;
- }
- },
- },
- {
- title: '排序',
- dataIndex: 'sort',
- width: 80
- },
- {
- title: '说明',
- dataIndex: 'description',
- ellipsis: true
- },
- {
- title: '显示',
- fixed: 'right',
- width: 60,
- dataIndex: 'hide',
- renderText: (_: any, record: any) => {
- return <Switch size='small' checked={_ == 1} onChange={(bool) => updateTable({ ...record, hide: bool ? 1 : 0 }, 'EDIT')} />
- }
- },
- {
- title: '操作',
- key: 'option',
- width: 200,
- fixed: 'right',
- valueType: 'option',
- render: (_: any, record: any) => {
- const { showAddRelation, parentId, calcType } = record;
- const btnGroup = true ? [
- <UpDataActBtn key={'addChild'} record={record} type='ADDCHILD' />,
- <UpDataActBtn key={'act'} record={record} type='EDIT' />,
- <Popconfirm
- title="是否确认删除?"
- key="del"
- onConfirm={() => delTableData(record)}
- >
- <a>删除</a>
- </Popconfirm>,
- ] : [
- <UpDataActBtn key={'act'} record={record} type='EDIT' />,
- <Popconfirm
- title="是否确认删除?"
- key="del"
- onConfirm={() => delTableData(record)}
- >
- <a>删除</a>
- </Popconfirm>,
- ]
- return showAddRelation ? [
- ...btnGroup,
- <a key="config3" onClick={() => {
- currentRow = record;
- if (showAddRelation == 1) oprnTableTransform(record, accountingSubjectColumn, 1);
- if (showAddRelation == 2) oprnTableTransform(record, shareParamsColumn, 2);
- if (showAddRelation == 3) oprnTableTransform(record, responsibilityColumn, 3);
- }}>
- {showAddRelation == 1
- ? '会计科目'
- : showAddRelation == 2
- ? '分摊层级'
- : showAddRelation == 3 && '责任中心'}
- </a>
- ] : btnGroup
- },
- },
- ]
- const getTableData = async (params: any) => {
- const { reportType } = params;
- if (reportType == undefined) return []
- const resp = await getReportProjectSettingList({ ...params });
- if (resp) {
- return {
- data: cleanTree(resp.list),
- success: true,
- total: resp.totalCount,
- pageSize: resp.pageSize,
- totalPage: resp.totalPage,
- }
- }
- return []
- }
- const delTableData = async (record: any) => {
- const resp = await delData([record.id]);
- if (resp) {
- message.success('操作成功!');
- tableRef.current?.reload();
- // message.success('操作成功!');
- }
- }
- const onSaveHandle = async (keys: Key[], rows: any[], record: any, settingType: number) => {
- let selectedRowKeysToStr: string[] = [];
- if (settingType == 2) {
- keys
- ? keys.map((item: any) => selectedRowKeysToStr.push(`${item}`))
- : [];
- }
- let selectedRowKeys: Key[] = [];
- if (settingType == 1) {
- selectedRowKeys = rows.map((a: any) => a.accountingCode)
- }
- if (settingType == 2) {
- selectedRowKeys = keys.map((a: any) => `${a}`)
- }
- if (settingType == 3) {
- selectedRowKeys = rows.map((a: any) => a.responsibilityCode)
- }
- const { id: reportId } = record;
- const resp = await saveReportRelation({
- reportId,
- reportType,
- relation: settingType,
- relationCodes: selectedRowKeys,
- });
- if (resp) {
- message.success('对照成功!');
- tableRef.current?.reload();
- }
- }
- const oprnTableTransform = (record: any, transferTableColumn: ProColumns[], settingType: number) => {
- const ref = React.createRef<{ save: any; }>();
- Modal.confirm({
- title: settingType == 1 ? `选择会计科目` : settingType == 2 ? '选择分摊层级' : '选择责任中心',
- icon: <></>,
- width: 1000,
- centered: true,
- okText: '确定',
- cancelText: '取消',
- content: <TableTransfer
- ref={ref}
- keyName={settingType == 1 ? `accountingCode` : settingType == 2 ? 'id' : 'responsibilityCode'}
- record={record}
- settingType={settingType}
- onSave={(keys, rows, settingType) => onSaveHandle(keys, rows, record, settingType)}
- leftColumns={transferTableColumn}
- rightColumns={transferTableColumn}
- ></TableTransfer>,
- onOk: () => {
- return ref.current && ref.current.save();
- }
- })
- }
- const updateTable = async (formVal: any, type: 'EDIT' | "ADD" | "ADDCHILD" | 'COPY') => {
- if (type == 'ADD' || type == 'ADDCHILD') {
- let parentId = 0;
- const { calcType = 0, calcFormula = '' } = formVal;
- (type == 'ADDCHILD') && (parentId = formVal.id);
- const result = {
- ...formVal,
- calcType,
- calcFormula,
- isLoss: formVal.isLoss ? 1 : 0,
- reportType: Number(reportType),
- parentId,
- decimalPlace:formVal.decimalPlace,
- permil: formVal.dataType === 1 ? (formVal.permil ? 1 : 0) : 0,
- }
- const resp = await addData(result);
- if (resp) {
- currentRow = undefined;
- tableRef.current?.reload();
- message.success('操作成功!');
- }
- }
- if (type == 'EDIT') {
- try {
- const { reportName, sort, calcType = 0, calcFormula = '', isLoss, parentId, id, fraction, costType, description, hide, dataType, decimalPlace, permil } = formVal;
- const result = {
- id,
- parentId,
- reportName,
- sort,
- reportType,
- calcType,
- calcFormula,
- fraction,
- costType,
- isLoss: isLoss ? 1 : 0,
- description,
- hide,
- dataType,
- decimalPlace:decimalPlace,
- permil: dataType === 1 ? (permil ? 1 : 0) : 0,
- };
- const resp = await editData(result);
- if (resp) {
- tableRef.current?.reload();
- message.success('操作成功!');
- }
- } catch (error) {
- console.log({ error });
- }
- }
- if (type == 'COPY') {
- //复制数据
- const { toReportType } = formVal;
- const resp = await copyDataToSelectedType({
- fromReportType: Number(reportType),
- toReportType,
- });
- if (resp) {
- message.success('复制成功!');
- tableRef.current?.reload();
- }
- }
- return true;
- }
- const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' | 'ADDCHILD' | 'COPY' }) => {
- const reportType = type == 'EDIT' || type == 'ADDCHILD' ? record.reportType : undefined
- return (
- <ModalForm
- title={type == 'COPY' ? '复制' : `${type == 'EDIT' ? '编辑' : '新增'}报表`}
- width={380}
- formRef={formRef}
- initialValues={type == 'EDIT' ? {
- ...record,
- permil: record.dataType === 1 ? !!record.permil : false,
- } : { dataType: 1, decimalPlaces: 2, permil: false }}
- trigger={
- type == 'EDIT' ? <a key="edit" >编辑</a> : type == 'ADDCHILD' ? <a className='add'>添加</a> : type == 'COPY' ? <span className='copy' style={{ marginRight: 8 }}>复制</span> : <span className='add'>新增</span>
- }
- onFinish={(val) => {
- return updateTable(type == 'EDIT' ? { ...record, ...val } : type == 'ADDCHILD' ? { ...val, id: record.id } : { ...val }, type);
- }}
- modalProps={{ destroyOnClose: true }}
- colProps={{ span: 24 }}
- grid
- >
- {
- type != 'COPY' && (
- <>
- <ProFormText
- label="报表名"
- rules={[
- {
- required: true,
- message: '报表名是必填项!',
- },
- ]}
- name="reportName"
- />
- <ProFormDigit
- label="排序"
- rules={[
- {
- required: true,
- message: '排序必填项!',
- },
- ]}
- name="sort"
- />
- {(
- //新增顶级不展示
- <>
- <ProFormSelect
- name="calcType"
- label="计算类型"
- options={[
- ...(calcTypes.map((a) => ({ label: a.name, value: Number(a.code) })))
- ]}
- placeholder="请选择状态"
- rules={[{ required: true, message: '请选择计算类型!' }]}
- />
- <ProFormDependency name={['calcType']}>
- {({ calcType }) => {
- // const resp = await getResponsibilityCenterList({pageSize:100,current:1});
- return calcType == 4 ? (
- <ProFormText
- label="计算公式"
- rules={[
- {
- required: true,
- message: '计算公式是必填项!',
- },
- ]}
- placeholder="例如:[1] + [2]"
- name="calcFormula"
- />
- ) : (
- <></>
- );
- }}
- </ProFormDependency>
- <ProFormDependency name={['calcType']}>
- {({ calcType }) => {
- // const resp = await getResponsibilityCenterList({pageSize:100,current:1});
- return calcType == 4 && reportType == 3 ? (
- <Form.Item
- name="isLoss"
- label="损益标志"
- valuePropName="checked"
- >
- <Switch size='small' />
- </Form.Item>
- ) : (
- <></>
- );
- }}
- </ProFormDependency>
- </>
- )}
- <ProFormSelect
- name="costType"
- label="报表项目类型"
- options={[
- { label: '收入', value: 1 },
- { label: '成本', value: 2 },
- ]}
- placeholder="请选择"
- rules={[{ required: true, message: '请选择报表项目类型!' }]}
- />
- <ProFormSelect
- name="fraction"
- label="占比计算类型"
- options={[
- { label: '分子', value: 1 },
- { label: '分母', value: 2 },
- { label: '不计算', value: 3 },
- ]}
- placeholder="请选择"
- rules={[{ required: true, message: '请选择占比计算类型!' }]}
- />
- <ProFormRadio.Group
- name="dataType"
- label="数据格式"
- options={[
- { label: '数值', value: 1 },
- { label: '百分比', value: 2 },
- ]}
- rules={[{ required: true }]}
- />
- <ProFormDependency name={['dataType']}>
- {({ dataType }) => {
- return dataType === 1 ? (
- <>
- <Row gutter={16}>
- <Col span={12}>
- <ProFormDigit
- label="小数位数"
- name="decimalPlace"
- min={0}
- max={10}
- fieldProps={{ precision: 0 }}
- rules={[{ required: true, message: '请输入小数位数!' }]}
- />
- </Col>
- <Col span={12}>
- <Form.Item
- label="是否需要千分号"
- name="permil"
- valuePropName="checked"
- style={{ marginBottom: '24px' }}
- >
- <Switch size='small' />
- </Form.Item>
- </Col>
- </Row>
- </>
- ) : <ProFormDigit
- label="小数位数"
- name="decimalPlace"
- min={0}
- max={10}
- fieldProps={{ precision: 0 }}
- rules={[{ required: true, message: '请输入小数位数!' }]}
- />;
- }}
- </ProFormDependency>
- <ProFormTextArea
- label="说明"
- placeholder='请输入'
- name="description"
- />
- </>
- )
- }
- {
- type == 'COPY' && (
- <ProFormSelect
- name="toReportType"
- label="复制到"
- width="sm"
- options={tabs.map((a) => ({ label: a.label, value: a.key }))}
- placeholder="请选择"
- rules={[{ required: true, message: '请选择复制到目标!' }]}
- />
- )
- }
- </ModalForm>
- )
- }
- const onTabChanged = (key: Key) => {
- set_reportType(key);
- set_tableDataFilterParams({ ...tableDataFilterParams, reportType: key })
- }
- const getTabs = async () => {
- const { systemId } = JSON.parse((localStorage.getItem('currentSelectedTab')) as string)
- const resp = await getDicDataBySysId(systemId, 'PROFIT_REPORT_TYPE');
- if (resp) {
- const { dataVoList } = resp;
- set_tabs(dataVoList.map((a: any) => ({ label: a.name, key: Number(a.code) })));
- set_tableDataFilterParams({ ...tableDataFilterParams, reportType: dataVoList.length > 0 ? dataVoList[0].code : undefined });
- set_reportType(dataVoList.length > 0 ? dataVoList[0].code : undefined);
- }
- }
- useEffect(() => {
- const fetchData = async () => {
- const { systemId } = JSON.parse(localStorage.getItem('currentSelectedTab') as string);
- const resp = await getDicDataBySysId(systemId, 'REPORT_ITEM_CALC_TYPE');
- setCalcTypes(resp?.dataVoList ?? []);
- };
- fetchData();
- getTabs();
- }, [])
- return (
- <KCIMPagecontainer className='ReportItemSet' title={false}>
- <div className='header'>
- <div className='pageTitle'>报表项目设置</div>
- <div className='btnGroup'>
- <span style={{ marginRight: 8, cursor: 'pointer' }} onClick={() => openRule()}><img style={{ width: 16, marginRight: 4, marginTop: -1 }} src={require('../../../../../static/tip.png')} />说明</span>
- <UpDataActBtn record={undefined} type='COPY' />
- <UpDataActBtn record={undefined} type='ADD' />
- </div>
- </div>
- <div className='toolBar' style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
- <Tabs
- defaultActiveKey={tabs.length > 0 ? tabs[0].key : undefined}
- items={tabs}
- key={'key'}
- onChange={(key) => onTabChanged(key)}
- />
- </div>
- <div>
- <KCIMTable pagination={false} scroll={{ x: 1700, y: `calc(100vh - 191px)` }} columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
- </div>
- </KCIMPagecontainer>
- )
- }
|