فهرست منبع

添加2023-11-08周功能

code4eat 1 سال پیش
والد
کامیت
245ef6d7db
53فایلهای تغییر یافته به همراه7763 افزوده شده و 128 حذف شده
  1. 58 24
      .umirc.ts
  2. 23 44
      src/app.tsx
  3. 5 0
      src/components/KCIMPageContainer/style.less
  4. 11 22
      src/pages/baseSetting/otherItemSet/reportItemSet/index.tsx
  5. 458 0
      src/pages/costAccounting/calcPageTemplate/columns.tsx
  6. 98 0
      src/pages/costAccounting/calcPageTemplate/config.ts
  7. 242 0
      src/pages/costAccounting/calcPageTemplate/index.tsx
  8. 109 0
      src/pages/costAccounting/calcPageTemplate/service.ts
  9. 47 0
      src/pages/costAccounting/calcPageTemplate/style.less
  10. 227 0
      src/pages/costAccounting/chargeItemCostCalc/index.tsx
  11. 41 0
      src/pages/costAccounting/chargeItemCostCalc/service.js
  12. 47 0
      src/pages/costAccounting/chargeItemCostCalc/style.less
  13. 263 0
      src/pages/costAccounting/patientCostCalc/index.tsx
  14. 41 0
      src/pages/costAccounting/patientCostCalc/service.js
  15. 47 0
      src/pages/costAccounting/patientCostCalc/style.less
  16. 204 0
      src/pages/costAccounting/unitPersonnelCostCalc/index.tsx
  17. 41 0
      src/pages/costAccounting/unitPersonnelCostCalc/service.js
  18. 47 0
      src/pages/costAccounting/unitPersonnelCostCalc/style.less
  19. 358 0
      src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/index.tsx
  20. 110 0
      src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/service.ts
  21. 55 0
      src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/style.less
  22. 370 0
      src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/index.tsx
  23. 102 0
      src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/service.ts
  24. 55 0
      src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/style.less
  25. 388 0
      src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/index.tsx
  26. 102 0
      src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/service.ts
  27. 55 0
      src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/style.less
  28. 532 0
      src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/index.tsx
  29. 132 0
      src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/service.ts
  30. 249 0
      src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/style.less
  31. 183 0
      src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/tableSelector.tsx
  32. 467 0
      src/pages/costLibraryManagement/reportMana/reportColumnMana/index.tsx
  33. 153 0
      src/pages/costLibraryManagement/reportMana/reportColumnMana/service.ts
  34. 74 0
      src/pages/costLibraryManagement/reportMana/reportColumnMana/style.less
  35. 132 0
      src/pages/costLibraryManagement/reportMana/reportColumnMana/transform.tsx
  36. 565 0
      src/pages/costLibraryManagement/reportMana/reportListMana/index.tsx
  37. 117 0
      src/pages/costLibraryManagement/reportMana/reportListMana/service.ts
  38. 254 0
      src/pages/costLibraryManagement/reportMana/reportListMana/style.less
  39. 203 0
      src/pages/costLibraryManagement/reportMana/reportListMana/tableSelector.tsx
  40. 359 0
      src/pages/costLibraryManagement/reportMana/reportNavSet/index.tsx
  41. 99 0
      src/pages/costLibraryManagement/reportMana/reportNavSet/service.ts
  42. 43 0
      src/pages/costLibraryManagement/reportMana/reportNavSet/style.less
  43. 4 4
      src/pages/monthlyInfoSearch/empCostDataImport/index.tsx
  44. 20 12
      src/pages/monthlyInfoSearch/patientChargeItemsImport/index.tsx
  45. 3 3
      src/pages/monthlyInfoSearch/patientChargeItemsImport/service.js
  46. 22 5
      src/pages/monthlyInfoSearch/patientInfoImport/index.tsx
  47. 332 0
      src/pages/reportCheck/report/index.tsx
  48. 46 0
      src/pages/reportCheck/report/service.ts
  49. 64 0
      src/pages/reportCheck/report/style.less
  50. 31 8
      src/pages/static/index.tsx
  51. 2 2
      src/utils/format.ts
  52. 70 1
      src/utils/tooljs.ts
  53. 3 3
      src/utils/zhongtaiC.js

+ 58 - 24
.umirc.ts

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2022-12-14 14:14:32
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-26 13:19:15
+ * @LastEditTime: 2023-11-07 17:34:18
  * @FilePath: /BudgetManaSystem/.umirc.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -21,13 +21,13 @@ export default defineConfig({
   qiankun: {
     slave: {},
   },
-  mfsu:false,
+  mfsu: false,
   lessLoader: {
-    modifyVars: { 
+    modifyVars: {
       '@ant-prefix': 'cost-ant',
       '@primary-color': '#3377FF',
-      '@border-color-base':'#dae2f2'
-    },  
+      '@border-color-base': '#dae2f2'
+    },
     javascriptEnabled: true,
   }, //对应修改生成的 antd 样式类名
 
@@ -35,7 +35,7 @@ export default defineConfig({
 
   access: {},
   model: {},
-  
+
   initialState: {},
   request: {},
   layout: {
@@ -112,7 +112,10 @@ export default defineConfig({
       path: '/costAccounting',
       name: '成本核算',
       routes: [
-       
+        {
+          path: '/costAccounting/:calcPageKey',
+          component: './costAccounting/calcPageTemplate/index',
+        }
       ],
     },
     {
@@ -120,11 +123,8 @@ export default defineConfig({
       name: '报表输出',
       routes: [
         {
-          path: '/reportExport/costAnalysisReport',
-          name: '成本分析报表',
-          routes: [
-            
-          ],
+          path: '/reportExport/report/:reportCode',
+          component: './reportCheck/report',
         },
       ],
     },
@@ -132,7 +132,7 @@ export default defineConfig({
       path: '/operationalAnalysis',
       name: '运营分析',
       routes: [
-        
+        {}
       ],
     },
     {
@@ -143,39 +143,73 @@ export default defineConfig({
           path: '/costLibraryManagement/basicCostManagement',
           name: '基础成本管理',
           routes: [
-            
+            {
+              path: '/costLibraryManagement/basicCostManagement/personnelClassificationMana',
+              name: '人事分类管理',
+              component: './costLibraryManagement/basicCostManagement/personnelClassificationMana/index',
+            },
+            {
+              path: '/costLibraryManagement/basicCostManagement/drugCostManagement',
+              name: '药品成本管理',
+              component: './costLibraryManagement/basicCostManagement/drugCostManagement/index',
+            },
+            {
+              path: '/costLibraryManagement/basicCostManagement/materialCostManagement',
+              name: '材料成本管理',
+              component: './costLibraryManagement/basicCostManagement/materialCostManagement/index',
+            },
+            {
+              path: '/costLibraryManagement/basicCostManagement/equipmentCostManagement',
+              name: '设备成本管理',
+              component: './costLibraryManagement/basicCostManagement/equipmentCostManagement/index',
+            },
           ],
         },
         {
           path: '/costLibraryManagement/projectCostManagement',
           name: '项目成本管理',
           routes: [
-            
+            {}
           ],
         },
         {
           path: '/costLibraryManagement/diseaseCostManagement',
           name: '病种成本管理',
           routes: [
-            
+            {}
           ],
         },
         {
           path: '/costLibraryManagement/clinicalPathwayCostManagement',
           name: '临床路径成本管理',
           routes: [
-            
+            {}
+          ],
+        },
+        {
+          path: '/costLibraryManagement/reportMana',
+          name: '报表管理',
+          routes: [
+            {
+              path: '/costLibraryManagement/reportMana/reportColumnMana',
+              name: '报表列管理',
+              component: './costLibraryManagement/reportMana/reportColumnMana/index',
+            },
+            {
+              path: '/costLibraryManagement/reportMana/reportListMana',
+              name: '报表管理',
+              component: './costLibraryManagement/reportMana/reportListMana/index',
+            },
+            {
+              path: '/costLibraryManagement/reportMana/reportNavSet',
+              name: '报表跳转',
+              component: './costLibraryManagement/reportMana/reportNavSet/index',
+            },
           ],
         },
       ],
     },
-    {
-      path: '/reportMana',
-      name: '报表管理',
-      routes: [
-        
-      ],
-    },
+
   ],
   npmClient: 'yarn',
 });

+ 23 - 44
src/app.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2022-12-14 14:14:32
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-26 10:59:52
+ * @LastEditTime: 2023-11-07 10:50:49
  * @FilePath: /BudgetManaSystem/src/app.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -278,7 +278,7 @@ export function patchClientRoutes({ routes }: { routes: any }) {
       lanhuPagePaths.forEach((a: any) => {
         treeData.routes.push(a);
       });
-      console.log({treeData});
+      
     }
     if (treeData.routes && treeData.routes.length > 0) {
       treeData.routes.forEach((a: any) => {
@@ -288,7 +288,10 @@ export function patchClientRoutes({ routes }: { routes: any }) {
 
   }
 
+ 
+
   treeLoop(routes[0]);
+ 
 }
 
 
@@ -415,42 +418,6 @@ export const layout = ({ initialState, setInitialState }: { initialState: any, s
             const _menu = processMenu(data);
 
             console.log({ _menu });
-            // const getVFromTree = (data: any[], key: string) => {
-            //   let result: any[] = [];
-            //   function looper(data: any[], key: string) {
-            //     data.forEach((t) => {
-            //       if (t[key] && t[key] != 0) {
-            //         //非一般页面
-            //         if (t[key] == 1 || t[key] == 2 || t[key] == 3) {
-            //           //网易有数页面
-            //           result.push({
-            //             contentType: t[key],
-            //             path: t['path'],
-            //             reportId: t['reportId'],
-            //             url: t['youshuUrl'],
-            //           });
-            //         }
-            //         if (t[key] == 5) {
-            //           result.push({
-            //             contentType: t[key],
-            //             path: t['path'],
-            //             reportId: t['reportId'],
-            //             url: t['softUrl'],
-            //           });
-            //         }
-
-            //       }
-            //       if (t.children && t.children.length > 0) {
-            //         looper(t.children, key);
-            //       }
-            //     });
-            //   }
-            //   looper(data, key);
-            //   return result;
-            // };
-
-            // const _menu = getVFromTree(data, 'contentType');
-
 
             setInitialState((t: any) => ({ ...t, spacicalPageParamsType: _menu, memuData: data, userData: JSON.parse(userData as string) }));
 
@@ -460,12 +427,24 @@ export const layout = ({ initialState, setInitialState }: { initialState: any, s
                 if (node.path == '/home') {
                   node.icon = <Icon component={imgNode} />;
                 }
-                if (node.path == '/baseInfoMana') {
-                  node.icon = <Icon component={fileIcon} />;
-                }
-                if (node.path == '/setting') {
+                if (node.path == '/baseSetting') {
                   node.icon = <Icon component={setting} />;
                 }
+                if (node.path == '/monthlyInfoSearch') {
+                  node.icon = <Icon component={()=><IconFont type='icon-yueduxinxicaiji' />} />;
+                }
+                if (node.path == '/costAccounting') {
+                  node.icon = <Icon component={()=><IconFont type='icon-jixiaoguanli' />} />;
+                }
+                if (node.path == '/reportExport') {
+                  node.icon = <Icon component={()=><IconFont type='icon-jixiaoguanli' />} />;
+                }
+                if (node.path == '/costLibraryManagement') {
+                  node.icon = <Icon component={()=><IconFont type='icon-chengbenkuguanli' />} />;
+                }
+                if (node.path == '/static') {
+                  node.icon = <Icon component={()=><IconFont type='icon-baobiaochaxun' />} />;
+                }
 
               }
               if (node.children) {
@@ -474,7 +453,7 @@ export const layout = ({ initialState, setInitialState }: { initialState: any, s
             }
 
             _menu.forEach((item: any) => {
-              addIconToPath(item, ['/home', '/baseInfoMana', '/setting',]);
+              addIconToPath(item, ['/home', '/baseInfoMana', '/costAccounting','/monthlyInfoSearch','/static','/reportExport','/costLibraryManagement','/baseSetting']);
             });
 
 
@@ -502,7 +481,7 @@ export const layout = ({ initialState, setInitialState }: { initialState: any, s
     collapsed: isCollapsed,
     // fixSiderbar:false,
     contentStyle: {
-      border: '16px solid #F7F9FC',
+      // border: '16px solid #F7F9FC',
       //height: '94.5vh',  //以去除顶部导航高度
       borderRadius: '22px',
       background: '#F7F9FC',

+ 5 - 0
src/components/KCIMPageContainer/style.less

@@ -1,5 +1,10 @@
+
+.cost-ant-pro-page-container {
+    border: 16px solid #F7F9FC !important;
+}
 .cost-ant-pro-page-container .cost-ant-pro-page-container-warp-page-header~.cost-ant-pro-grid-content .cost-ant-pro-page-container-children-content {
     padding-block: 0 !important;
+    
 }
 
 .cost-ant-pro-page-container-children-content {

+ 11 - 22
src/pages/baseSetting/otherItemSet/reportItemSet/index.tsx

@@ -2,16 +2,16 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-24 14:39:32
+ * @LastEditTime: 2023-10-30 14:04:24
  * @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 { ModalForm, ProFormText } from '@ant-design/pro-form';
 
-import { message, Tabs, Popconfirm } from 'antd';
+import { Tabs, Popconfirm } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 
 import { addData, delData, editData, getData, getTabs } from './service';
@@ -20,24 +20,16 @@ import './style.less';
 
 import KCIMPagecontainer from '@/components/KCIMPageContainer';
 import { KCIMTable } from '@/components/KCIMTable';
-import KCIMDrawerForm from '@/components/KCIMDrawerForm';
-import { set } from 'lodash';
+
 import { ProFormDependency, ProFormDigit, ProFormInstance, ProFormRadio, ProFormSelect } from '@ant-design/pro-components';
 import { getTargetDic } from '@/services/auth';
-// import TableTransfer from './transform';
-// import TableSelecter from './tableSelector';
-// import { getCheckData } from '../checkGroupMana/service';
 
-const IconFont = createFromIconfontCN({
-  scriptUrl: '',
-});
 
 export default function reportItemSet() {
 
   const tableRef = useRef();
   const [tabs, set_tabs] = useState<any[]>([]);
 
-
   const [currentEdit, set_currentEdit] = useState<any|undefined>(undefined);
   const [tableData, set_tableData] = useState<any[]>([]);
   const [currentTab, set_currentTab] = useState<any|undefined>(undefined);
@@ -152,7 +144,7 @@ export default function reportItemSet() {
       <ModalForm
         title={`${type == 'EDIT' ? '编辑' :record?'添加':'新增'}报表`}
         width={400}
-        initialValues={type == 'EDIT' ? { ...record,redirectParameter:record.redirectParameter?record.redirectParameter.split(','):[]} : { computeType: 1, dataType: 1 }}
+        initialValues={type == 'EDIT' ? { ...record,redirectParameter:record.redirectParameter?record.redirectParameter.split(','):[]} : {computeType:1,dataType:1 }}
         trigger={type == 'EDIT' ? <a key="edit">编辑</a> : <a className="add" >{record?'添加':'新增'}</a>}
         onFinish={(val) => {
           set_currentEdit(undefined);
@@ -186,9 +178,8 @@ export default function reportItemSet() {
                   label="报表项目类别:"
                   request={async () => {
                     const resp = await getTargetDic('REPORT_ITEM_TYPE');
-                    const { data, status } = resp;
-                    if (status == 200) {
-                      const { dataVoList } = data;
+                    if (resp) {
+                      const { dataVoList } = resp;
                       return dataVoList.map((a:any) => {
                         if(a.defaultValue&&type == 'ADD'){
                             formRef.current?.setFieldValue('computeSource',a.code);
@@ -235,9 +226,8 @@ export default function reportItemSet() {
           label="下钻界面:"
           request={async () => {
             const resp = await getTargetDic('REPORT_REDIRECT_PATH');
-            const { data, status } = resp;
-            if (status == 200) {
-              const { dataVoList } = data;
+            if (resp) {
+              const { dataVoList } = resp;
               return dataVoList.map((a:any) => {
                   if(a.defaultValue&&type == 'ADD'){
                     formRef.current?.setFieldValue('redirect',a.code);
@@ -259,9 +249,8 @@ export default function reportItemSet() {
                         fieldProps={{mode:'multiple'}}
                         request={async () => {
                             const resp = await getTargetDic('REPORT_REDIRECT_PARAM');
-                            const { data, status } = resp;
-                            if (status == 200) {
-                            const { dataVoList } = data;
+                            if (resp) {
+                            const { dataVoList } = resp;
                             return dataVoList.map((a:any) => {
                                 if(a.defaultValue&&type == 'ADD'){
                                     formRef.current?.setFieldValue('redirectParameter',a.value?a.value.split(','):[]);

+ 458 - 0
src/pages/costAccounting/calcPageTemplate/columns.tsx

@@ -0,0 +1,458 @@
+import { formatMoneyNumber } from "@/utils/format";
+import { ProColumns } from "@ant-design/pro-components";
+
+
+
+
+export const unitPersonnelCostCalc: ProColumns[] = [
+    {
+        title: '人事分类名称',
+        dataIndex: 'name',
+    },
+    {
+        title: '实际编制人数',
+        dataIndex: 'empNum',
+    },
+    {
+        title: '实际总工时',
+        dataIndex: 'actualHour',
+    },
+    {
+        title: '预计总工时',
+        dataIndex: 'expectHour',
+    },
+    {
+        title: '总成本',
+        dataIndex: 'totalCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '人均成本',
+        dataIndex: 'avgCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '每分钟成本',
+        dataIndex: 'minuteCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+];
+
+
+export const chargeItemCostCalc: ProColumns[] = [
+    {
+        title: '收费项目编码',
+        dataIndex: 'code',
+    },
+    {
+        title: '收费项目名称',
+        dataIndex: 'name',
+    },
+    {
+        title: '项目类别',
+        dataIndex: 'itemType',
+    },
+    {
+        title: '药品收入',
+        dataIndex: 'drugIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料收入',
+        dataIndex: 'materialIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目收入',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品成本',
+        dataIndex: 'drugCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料成本',
+        dataIndex: 'materialCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目成本',
+        dataIndex: 'itemCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '人力成本',
+        dataIndex: 'empCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '设备成本',
+        dataIndex: 'equipmentCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '空间成本',
+        dataIndex: 'spaceCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+];
+
+
+export const patientCostCalc: ProColumns[] = [
+    {
+        title: '住院号/门诊号',
+        dataIndex: 'visitNo',
+    },
+    {
+        title: '病人ID',
+        dataIndex: 'patientNo',
+    },
+    {
+        title: '患者姓名',
+        dataIndex: 'name',
+    },
+    {
+        title: '科室代码',
+        dataIndex: 'departmentCode',
+    },
+    {
+        title: '科室名称',
+        dataIndex: 'departmentName',
+    },
+    {
+        title: '人力成本',
+        dataIndex: 'empCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '设备成本',
+        dataIndex: 'equipmentCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '空间成本',
+        dataIndex: 'spaceCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目成本',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品成本',
+        dataIndex: 'drugCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料成本',
+        dataIndex: 'materialCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目收入',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品收入',
+        dataIndex: 'drugIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料收入',
+        dataIndex: 'materialIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+
+    },
+];
+
+
+export const diseaseCostCalculation: ProColumns[] = [
+    {
+        title: '病种代码',
+        dataIndex: 'code',
+    },
+    {
+        title: '病种名称',
+        dataIndex: 'name',
+    },
+    {
+        title: '科室代码',
+        dataIndex: 'departmentCode',
+    },
+    {
+        title: '科室名称',
+        dataIndex: 'departmentName',
+    },
+    {
+        title: '人力成本',
+        dataIndex: 'empCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '设备成本',
+        dataIndex: 'equipmentCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '空间成本',
+        dataIndex: 'spaceCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目成本',
+        dataIndex: 'itemCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品成本',
+        dataIndex: 'drugCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料成本',
+        dataIndex: 'materialCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目收入',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品收入',
+        dataIndex: 'drugIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料收入',
+        dataIndex: 'materialIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    }
+];
+
+export const DRG_DIPCostCalc: ProColumns[] = [
+    {
+        title: '分组代码',
+        dataIndex: 'code',
+    },
+    {
+        title: '分组名称',
+        dataIndex: 'name',
+    },
+    {
+        title: '科室代码',
+        dataIndex: 'departmentCode',
+    },
+    {
+        title: '科室名称',
+        dataIndex: 'departmentName',
+    },
+    {
+        title: '人力成本',
+        dataIndex: 'empCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '设备成本',
+        dataIndex: 'equipmentCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '空间成本',
+        dataIndex: 'spaceCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目成本',
+        dataIndex: 'itemCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品成本',
+        dataIndex: 'drugCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料成本',
+        dataIndex: 'materialCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目收入',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品收入',
+        dataIndex: 'drugIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料收入',
+        dataIndex: 'materialIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    }
+];
+export const clinicalPathway: ProColumns[] = [
+    {
+        title: '路径代码',
+        dataIndex: 'code',
+    },
+    {
+        title: '路径名称',
+        dataIndex: 'name',
+    },
+    {
+        title: '科室代码',
+        dataIndex: 'departmentCode',
+    },
+    {
+        title: '科室名称',
+        dataIndex: 'departmentName',
+    },
+    {
+        title: '人力成本',
+        dataIndex: 'empCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '设备成本',
+        dataIndex: 'equipmentCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '空间成本',
+        dataIndex: 'spaceCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目成本',
+        dataIndex: 'itemCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品成本',
+        dataIndex: 'drugCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料成本',
+        dataIndex: 'materialCost',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '项目收入',
+        dataIndex: 'itemIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '药品收入',
+        dataIndex: 'drugIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    },
+    {
+        title: '材料收入',
+        dataIndex: 'materialIncome',
+        renderText(num, record, index, action) {
+            return formatMoneyNumber(num);
+        },
+    }
+];

+ 98 - 0
src/pages/costAccounting/calcPageTemplate/config.ts

@@ -0,0 +1,98 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-11-01 11:13:38
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 10:34:01
+ * @FilePath: /CostAccountingSys/src/pages/costAccounting/calcPageTemplate/config.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+import { getTargetDic } from "@/services/auth";
+
+
+
+export const unitPersonnelCostCalcFilterConf = [
+    {
+        type:'input',
+        label:'检索:',
+        placeholder:'人事分类',
+        key:'filter'
+    }
+]
+
+export const patientCostCalcFilterConf = [
+    {
+        type:'input',
+        label:'科室名称:',
+        placeholder:'请输入',
+        key:'departmentName'
+    },
+    {
+        type:'input',
+        label:'患者姓名:',
+        placeholder:'请输入',
+        key:'patientName'
+    }
+]
+
+export const chargeItemCostCalcFilterConf = [
+    {
+        type:'select',
+        label:'项目类别:',
+        placeholder:'请输入',
+        key:'itemType',
+        request:async ()=>{
+            const resp = await getTargetDic('CHARGE_ITEM_TYPE');
+            if (resp) {
+              const { dataVoList } = resp;
+              return dataVoList.map((a:any) => ({ label: a.name, value: a.code }));
+            }
+        }
+    },
+    {
+        type:'input',
+        label:'检索:',
+        placeholder:'请输入收费项目名称',
+        key:'itemName'
+    }
+]
+
+
+export const diseaseCostCalculationFilterConf = [
+    {
+        type:'input',
+        label:'科室名称:',
+        placeholder:'请输入',
+        key:'departmentName'
+    },
+    {
+        type:'input',
+        label:'病种名称:',
+        placeholder:'请输入',
+        key:'diseaseName'
+    }
+]
+
+export const DRG_DIPCostCalcFilterConf = [
+    {
+        type:'input',
+        label:'科室名称:',
+        placeholder:'请输入',
+        key:'departmentName'
+    },
+    {
+        type:'input',
+        label:'分组名称:',
+        placeholder:'请输入',
+        key:'groupName'
+    }
+]
+
+export const clinicalPathwayFilterConf = [
+    {
+        type:'input',
+        label:'路径名称:',
+        placeholder:'请输入',
+        key:'clinicalName'
+    }
+]

+ 242 - 0
src/pages/costAccounting/calcPageTemplate/index.tsx

@@ -0,0 +1,242 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 17:39:42
+ * @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 } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import { calculateReq, getData } 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, ProFormSelect } from '@ant-design/pro-components';
+import { formatMoneyNumber } from '@/utils/format';
+import { getTargetDic } from '@/services/auth';
+import { useParams } from '@umijs/max';
+import { chargeItemCostCalc, diseaseCostCalculation, DRG_DIPCostCalc, patientCostCalc, unitPersonnelCostCalc } from './columns';
+import { chargeItemCostCalcFilterConf, clinicalPathwayFilterConf, diseaseCostCalculationFilterConf, DRG_DIPCostCalcFilterConf, patientCostCalcFilterConf, unitPersonnelCostCalcFilterConf } from './config';
+
+
+const IconFont = createFromIconfontCN({
+  scriptUrl: '',
+});
+
+const currentData = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`
+
+export default function calcPageTemplate() {
+  const [computeDate, set_computeDate] = useState(currentData);
+  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate: currentData });
+  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(1000);
+
+  const getTableData = async (params: any) => {
+    const resp = await getData({ ...params, ...tableDataFilterParams });
+    if (resp) {
+      let data = resp.list?resp.list:resp
+      if(params.calcPageKey == 'unitPersonnelCostCalc'){
+        data = data.map((a:any) => ({ ...a, children: a.childList }))
+      }
+      return {
+        data:data,
+        success: true,
+        total: resp.totalCount,
+        pageSize: resp.pageSize,
+        totalPage: resp.totalPage,
+        
+      };
+
+    }
+    return [];
+  };
+
+  const tableDataSearchHandle = (paramName: string) => {
+
+    set_tableDataFilterParams({
+      ...tableDataFilterParams,
+      [`${paramName}`]: tableDataSearchKeywords
+    })
+
+  }
+
+  const calcFunc = () => {
+
+    Modal.confirm({
+      title: '注意',
+      content: '计算操作会覆盖当月已计算的数据,是否继续操作?',
+      okText:'确定',
+      cancelText:'取消',
+      onOk: async (...args) => {
+        set_loading(true);
+        const resp = await calculateReq(computeDate, params.calcPageKey);
+        if (resp) {
+
+          set_loading(false);
+          message.success('操作成功!');
+          tableRef.current?.reload();
+        } else {
+          set_loading(false);
+        }
+      },
+    })
+  }
+
+  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
+              suffix={
+                <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle(`${key}`)} />
+              }
+              onChange={(e) => {
+                set_tableDataSearchKeywords(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>
+        )
+      }
+      return <></>
+    });
+
+    return nodes;
+  }
+
+
+
+  useEffect(() => {
+    const { calcPageKey } = params;
+    if (calcPageKey == "chargeItemCostCalc") {
+      set_columns(chargeItemCostCalc);
+      set_filterConf(chargeItemCostCalcFilterConf);
+    }
+    if (calcPageKey == "patientCostCalc") {
+      set_columns(patientCostCalc);
+      set_scrollX(1500);
+      set_filterConf(patientCostCalcFilterConf);
+    }
+    if (calcPageKey == "unitPersonnelCostCalc") {
+      set_columns(unitPersonnelCostCalc);
+      set_scrollX(1000);
+      set_filterConf(unitPersonnelCostCalcFilterConf);
+    }
+    if (calcPageKey == "diseaseCostCalculation") {
+      set_columns(diseaseCostCalculation);
+      set_scrollX(1500);
+      set_filterConf(diseaseCostCalculationFilterConf);
+    }
+    if (calcPageKey == "DRG_DIPCostCalc") {
+      set_columns(DRG_DIPCostCalc);
+      set_scrollX(1500);
+      set_filterConf(DRG_DIPCostCalcFilterConf);
+    }
+    if (calcPageKey == "clinicalPathway") {
+      set_columns(DRG_DIPCostCalc);
+      set_scrollX(1500);
+      set_filterConf(clinicalPathwayFilterConf);
+    }
+
+
+    set_tableDataFilterParams({ computeDate, calcPageKey });
+  }, [params]);
+
+  return (
+    <KCIMPagecontainer className="calcPageTemplate" title={false}>
+      <div className="toolBar">
+        <div className="filter">
+          <div className="filterItem">
+            {
+              <div className="search">
+                <span>核算年月:</span>
+                <DatePicker
+                  onChange={(data, dateString) => {
+                    set_computeDate(dateString);
+                    set_tableDataFilterParams({
+                      ...tableDataFilterParams,
+                      computeDate: dateString,
+                    });
+                  }}
+                  picker="month"
+                  locale={locale}
+                  defaultValue={moment(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`, 'YYYY-MM')}
+                  format="YYYY-MM"
+                  placeholder="选择年月"
+                />
+              </div>
+            }
+          </div>
+          {generateFilterItems(filterConf)}
+        </div>
+        <div className="btnGroup">
+          <a className='calc' onClick={() => calcFunc()}>计算</a>
+        </div>
+      </div>
+      <div style={{ marginTop: 16 }}>
+        <KCIMTable
+          columns={columns}
+          actionRef={tableRef}
+          rowKey="id"
+          scroll={{x:scrollX}}
+          params={tableDataFilterParams}
+          request={(params) => getTableData(params)}
+        />
+      </div>
+    </KCIMPagecontainer>
+  );
+}

+ 109 - 0
src/pages/costAccounting/calcPageTemplate/service.ts

@@ -0,0 +1,109 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-01 14:21:47
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export const getData = (params: any) => {
+
+  const {calcPageKey,...next} = params;
+  
+  if(calcPageKey == 'unitPersonnelCostCalc'){
+    return request('/costAccount/calculate/empCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+  if(calcPageKey == 'patientCostCalc'){
+    return request('/costAccount/calculate/patientCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+  if(calcPageKey == 'chargeItemCostCalc'){
+    return request('/costAccount/calculate/itemCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+  if(calcPageKey == 'diseaseCostCalculation'){
+    return request('/costAccount/calculate/diseaseCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+  if(calcPageKey == 'DRG_DIPCostCalc'){
+    return request('/costAccount/calculate/groupCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+  if(calcPageKey == 'clinicalPathway'){
+    return request('/costAccount/calculate/clinicalPathwayCostCalculateList', {
+      method: 'GET',
+      params:{...next}
+    });
+  }
+};
+
+//计算
+export const calculateReq = (computeDate: string,calcPageKey: string | undefined) => {
+  if(calcPageKey == 'unitPersonnelCostCalc'){
+    return request('/costAccount/calculate/empCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  if(calcPageKey == 'patientCostCalc'){
+    return request('/costAccount/calculate/patientCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  if(calcPageKey == 'chargeItemCostCalc'){
+    return request('/costAccount/calculate/itemCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  if(calcPageKey == 'diseaseCostCalculation'){
+    return request('/costAccount/calculate/diseaseCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  if(calcPageKey == 'DRG_DIPCostCalc'){
+    return request('/costAccount/calculate/groupCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  if(calcPageKey == 'clinicalPathway'){
+    return request('/costAccount/calculate/clinicalPathwayCostCalculate', {
+      method: 'POST',
+      params:{computeDate}
+    });
+  }
+  
+};
+
+
+
+
+
+
+
+
+
+
+
+

+ 47 - 0
src/pages/costAccounting/calcPageTemplate/style.less

@@ -0,0 +1,47 @@
+
+
+.calcPageTemplate {
+  position: relative;
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      
+      .calc {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 227 - 0
src/pages/costAccounting/chargeItemCostCalc/index.tsx

@@ -0,0 +1,227 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-01 09:52:42
+ * @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 } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import { calculateReq, getData } 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, ProFormSelect } from '@ant-design/pro-components';
+import { formatMoneyNumber } from '@/utils/format';
+import { getTargetDic } from '@/services/auth';
+
+
+const IconFont = createFromIconfontCN({
+  scriptUrl: '',
+});
+
+const currentData = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`
+
+export default function chargeItemCostCalc() {
+  const [computeDate, set_computeDate] = useState(currentData);
+  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate: currentData });
+  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
+  const tableRef = useRef<ActionType>();
+  const [loading, set_loading] = useState(false);
+
+  const columns: ProColumns[] = [
+    {
+      title: '人事分类名称',
+      dataIndex: 'name',
+    },
+    {
+      title: '实际编制人数',
+      dataIndex: 'empNum',
+    },
+    {
+      title: '实际总工时',
+      dataIndex: 'actualHour',
+    },
+    {
+      title: '预计总工时',
+      dataIndex: 'expectHour',
+    },
+    {
+      title: '总成本',
+      dataIndex: 'totalCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '人均成本',
+      dataIndex: 'avgCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '每分钟成本',
+      dataIndex: 'minuteCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+  ];
+
+  const getTableData = async (params: any) => {
+    const resp = await getData({ ...params, ...tableDataFilterParams });
+    if (resp) {
+      // function renameChildListToChildren(node: any) {
+      //   if (node.childList) {
+      //     node.children = node.childList;
+      //   }
+
+      //   if (node.children && node.children.length > 0) {
+      //     node.children.forEach((child: any) => renameChildListToChildren(child));
+      //   }
+      // }
+
+      // resp.forEach((tree: any) => renameChildListToChildren(tree));
+
+      return {
+        data: resp.list,
+        success: true
+      };
+    }
+    return [];
+  };
+
+  const tableDataSearchHandle = (paramName: string) => {
+
+
+    set_tableDataFilterParams({
+      ...tableDataFilterParams,
+      [`${paramName}`]: tableDataSearchKeywords
+    })
+  }
+
+  const calcFunc = () => {
+
+    Modal.confirm({
+      title: '注意',
+      content: '计算操作会覆盖当月已计算的数据,是否继续操作?',
+
+      onOk: async (...args) => {
+        set_loading(true);
+        const resp = await calculateReq(computeDate);
+        if (resp) {
+
+          set_loading(false);
+          message.success('操作成功!');
+          tableRef.current?.reload();
+        } else {
+          set_loading(false);
+        }
+      },
+    })
+  }
+
+
+
+  useEffect(() => { }, []);
+
+  return (
+    <KCIMPagecontainer className="chargeItemCostCalc" title={false}>
+      <div className="toolBar">
+        <div className="filter">
+          <div className="filterItem">
+            {
+              <div className="search">
+                <span>核算年月:</span>
+                <DatePicker
+                  onChange={(data, dateString) => {
+                    set_computeDate(dateString);
+                    set_tableDataFilterParams({
+                      ...tableDataFilterParams,
+                      computeDate: dateString,
+                    });
+                  }}
+                  picker="month"
+                  locale={locale}
+                  defaultValue={moment(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`, 'YYYY-MM')}
+                  format="YYYY-MM"
+                  placeholder="选择年月"
+                />
+              </div>
+            }
+          </div>
+          <div className='filterItem' style={{ marginLeft: 16 }}>
+              <span className='label'>项目类别:</span>
+              <ProFormSelect
+                  noStyle
+                  allowClear
+                  placeholder="请选择"
+                  style={{ width: 160, marginRight: 16 }}
+                  request={async () => {
+                    const resp = await getTargetDic('CHARGE_ITEM_TYPE');
+                    if (resp) {
+                      const { dataVoList } = resp;
+                      return dataVoList.map((a:any) => ({ label: a.name, value: a.code }));
+                    }
+                    return [];
+                  }}
+                  fieldProps={{
+                      onChange(value, option) {
+                          set_tableDataFilterParams({ ...tableDataFilterParams,itemType: value })
+                      },
+                  }}
+              />
+          </div>
+          <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
+            <span className='label' style={{ whiteSpace: 'nowrap' }}> 检索:</span>
+            <Input placeholder={'收费项目'} allowClear
+              suffix={
+                <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('itemName')} />
+              }
+              onChange={(e) => {
+                set_tableDataSearchKeywords(e.target.value);
+                if (e.target.value.length == 0) {
+                  set_tableDataFilterParams({
+                    ...tableDataFilterParams,
+                    itemName: ''
+                  });
+                }
+              }}
+              onPressEnter={(e) => {
+                set_tableDataFilterParams({
+                  ...tableDataFilterParams,
+                  itemName: ((e.target) as HTMLInputElement).value
+                });
+              }}
+
+            />
+          </div>
+        </div>
+        <div className="btnGroup">
+          <a className='calc' onClick={() => calcFunc()}>计算</a>
+        </div>
+      </div>
+      <div style={{ marginTop: 16 }}>
+        <KCIMTable
+          columns={columns}
+          actionRef={tableRef}
+          rowKey="id"
+
+          params={tableDataFilterParams}
+          request={(params) => getTableData(params)}
+        />
+      </div>
+    </KCIMPagecontainer>
+  );
+}

+ 41 - 0
src/pages/costAccounting/chargeItemCostCalc/service.js

@@ -0,0 +1,41 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-10-31 10:01:55
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export const getData = (params) => {
+  return request('/costAccount/calculate/itemCostCalculateList', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+//计算
+export const calculateReq = (computeDate) => {
+  return request('/costAccount/calculate/itemCostCalculate', {
+    method: 'POST',
+    params:{computeDate}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+
+

+ 47 - 0
src/pages/costAccounting/chargeItemCostCalc/style.less

@@ -0,0 +1,47 @@
+
+
+.chargeItemCostCalc {
+  position: relative;
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      
+      .calc {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 263 - 0
src/pages/costAccounting/patientCostCalc/index.tsx

@@ -0,0 +1,263 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-01 10:04:17
+ * @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 } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import { calculateReq, getData } 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 } from '@ant-design/pro-components';
+import { formatMoneyNumber } from '@/utils/format';
+
+
+const IconFont = createFromIconfontCN({
+  scriptUrl: '',
+});
+
+const currentData = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`
+
+export default function patientCostCalc() {
+  const [computeDate, set_computeDate] = useState(currentData);
+  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate: currentData });
+  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
+  const tableRef = useRef<ActionType>();
+  const [loading, set_loading] = useState(false);
+
+  const columns: ProColumns[] = [
+    {
+      title: '住院号/门诊号',
+      dataIndex: 'visitNo',
+    },
+    {
+      title: '病人ID',
+      dataIndex: 'patientNo',
+    },
+    {
+      title: '患者姓名',
+      dataIndex: 'name',
+    },
+    {
+      title: '科室代码',
+      dataIndex: 'departmentCode',
+    },
+    {
+      title: '科室名称',
+      dataIndex: 'departmentName',
+    },
+    {
+      title: '人力成本',
+      dataIndex: 'empCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '设备成本',
+      dataIndex: 'equipmentCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '空间成本',
+      dataIndex: 'spaceCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '项目成本',
+      dataIndex: 'itemIncome',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '药品成本',
+      dataIndex: 'drugCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '材料成本',
+      dataIndex: 'materialCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '项目收入',
+      dataIndex: 'itemIncome',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '药品收入',
+      dataIndex: 'drugIncome',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '材料收入',
+      dataIndex: 'materialIncome',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+
+    },
+  ];
+
+  const getTableData = async (params: any) => {
+    const resp = await getData({ ...params, ...tableDataFilterParams });
+    if (resp) {
+      return {
+        data: resp.list,
+        success: true
+      };
+    }
+    return [];
+  };
+
+  const tableDataSearchHandle = (paramName: string) => {
+
+
+    set_tableDataFilterParams({
+      ...tableDataFilterParams,
+      [`${paramName}`]: tableDataSearchKeywords
+    })
+  }
+
+  const calcFunc = () => {
+
+    Modal.confirm({
+      title: '注意',
+      content: '计算操作会覆盖当月已计算的数据,是否继续操作?',
+
+      onOk: async (...args) => {
+        set_loading(true);
+        const resp = await calculateReq(computeDate);
+        if (resp) {
+
+          set_loading(false);
+          message.success('操作成功!');
+          tableRef.current?.reload();
+        } else {
+          set_loading(false);
+        }
+      },
+    })
+  }
+
+
+
+  useEffect(() => { }, []);
+
+  return (
+    <KCIMPagecontainer className="patientCostCalc" title={false}>
+      <div className="toolBar">
+        <div className="filter">
+          <div className="filterItem">
+            {
+              <div className="search">
+                <span>核算年月:</span>
+                <DatePicker
+                  onChange={(data, dateString) => {
+                    set_computeDate(dateString);
+                    set_tableDataFilterParams({
+                      ...tableDataFilterParams,
+                      computeDate: dateString,
+                    });
+                  }}
+                  picker="month"
+                  locale={locale}
+                  defaultValue={moment(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`, 'YYYY-MM')}
+                  format="YYYY-MM"
+                  placeholder="选择年月"
+                />
+              </div>
+            }
+          </div>
+          <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
+            <span className='label' style={{ whiteSpace: 'nowrap' }}> 科室名称:</span>
+            <Input placeholder={'人事分类'} allowClear
+              suffix={
+                <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('departmentName')} />
+              }
+              onChange={(e) => {
+                set_tableDataSearchKeywords(e.target.value);
+                if (e.target.value.length == 0) {
+                  set_tableDataFilterParams({
+                    ...tableDataFilterParams,
+                    departmentName: ''
+                  });
+                }
+              }}
+              onPressEnter={(e) => {
+                set_tableDataFilterParams({
+                  ...tableDataFilterParams,
+                  departmentName: ((e.target) as HTMLInputElement).value
+                });
+              }}
+
+            />
+          </div>
+          <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
+            <span className='label' style={{ whiteSpace: 'nowrap' }}> 患者姓名:</span>
+            <Input placeholder={'人事分类'} allowClear
+              suffix={
+                <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('patientName')} />
+              }
+              onChange={(e) => {
+                set_tableDataSearchKeywords(e.target.value);
+                if (e.target.value.length == 0) {
+                  set_tableDataFilterParams({
+                    ...tableDataFilterParams,
+                    patientName: ''
+                  });
+                }
+              }}
+              onPressEnter={(e) => {
+                set_tableDataFilterParams({
+                  ...tableDataFilterParams,
+                  patientName: ((e.target) as HTMLInputElement).value
+                });
+              }}
+
+            />
+          </div>
+        </div>
+        <div className="btnGroup">
+          <a className='calc' onClick={() => calcFunc()}>计算</a>
+        </div>
+      </div>
+      <div style={{ marginTop: 16 }}>
+        <KCIMTable
+          columns={columns}
+          actionRef={tableRef}
+          rowKey="id"
+
+          params={tableDataFilterParams}
+          request={(params) => getTableData(params)}
+        />
+      </div>
+    </KCIMPagecontainer>
+  );
+}

+ 41 - 0
src/pages/costAccounting/patientCostCalc/service.js

@@ -0,0 +1,41 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-01 09:55:02
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export const getData = (params) => {
+  return request('/costAccount/calculate/patientCostCalculateList', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+//计算
+export const calculateReq = (computeDate) => {
+  return request('/costAccount/calculate/patientCostCalculate', {
+    method: 'POST',
+    params:{computeDate}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+
+

+ 47 - 0
src/pages/costAccounting/patientCostCalc/style.less

@@ -0,0 +1,47 @@
+
+
+.patientCostCalc {
+  position: relative;
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      
+      .calc {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 204 - 0
src/pages/costAccounting/unitPersonnelCostCalc/index.tsx

@@ -0,0 +1,204 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-10-30 11:12:12
+ * @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 } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import { calculateReq, getData } 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 } from '@ant-design/pro-components';
+import { formatMoneyNumber } from '@/utils/format';
+
+
+const IconFont = createFromIconfontCN({
+  scriptUrl: '',
+});
+
+const currentData = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`
+
+export default function unitPersonnelCostCalc() {
+  const [computeDate, set_computeDate] = useState(currentData);
+  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any>({ computeDate: currentData });
+  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
+  const tableRef = useRef<ActionType>();
+  const [loading, set_loading] = useState(false);
+
+  const columns: ProColumns[] = [
+    {
+      title: '人事分类名称',
+      dataIndex: 'name',
+    },
+    {
+      title: '实际编制人数',
+      dataIndex: 'empNum',
+    },
+    {
+      title: '实际总工时',
+      dataIndex: 'actualHour',
+    },
+    {
+      title: '预计总工时',
+      dataIndex: 'expectHour',
+    },
+    {
+      title: '总成本',
+      dataIndex: 'totalCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '人均成本',
+      dataIndex: 'avgCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+    {
+      title: '每分钟成本',
+      dataIndex: 'minuteCost',
+      renderText(num, record, index, action) {
+        return formatMoneyNumber(num);
+      },
+    },
+  ];
+
+  const getTableData = async (params: any) => {
+    const resp = await getData({ ...params, ...tableDataFilterParams });
+    if (resp) {
+      function renameChildListToChildren(node: any) {
+        if (node.childList) {
+          node.children = node.childList;
+        }
+
+        if (node.children && node.children.length > 0) {
+          node.children.forEach((child: any) => renameChildListToChildren(child));
+        }
+      }
+
+      resp.forEach((tree: any) => renameChildListToChildren(tree));
+
+      return {
+        data: resp,
+        success: true
+      };
+    }
+    return [];
+  };
+
+  const tableDataSearchHandle = (paramName: string) => {
+
+
+    set_tableDataFilterParams({
+      ...tableDataFilterParams,
+      [`${paramName}`]: tableDataSearchKeywords
+    })
+  }
+
+  const calcFunc = () => {
+
+    Modal.confirm({
+      title: '注意',
+      content: '计算操作会覆盖当月已计算的数据,是否继续操作?',
+
+      onOk: async (...args) => {
+        set_loading(true);
+        const resp = await calculateReq(computeDate);
+        if (resp) {
+
+          set_loading(false);
+          message.success('操作成功!');
+          tableRef.current?.reload();
+        } else {
+          set_loading(false);
+        }
+      },
+    })
+  }
+
+
+
+  useEffect(() => { }, []);
+
+  return (
+    <KCIMPagecontainer className="unitPersonnelCostCalc" title={false}>
+      <div className="toolBar">
+        <div className="filter">
+          <div className="filterItem">
+            {
+              <div className="search">
+                <span>核算年月:</span>
+                <DatePicker
+                  onChange={(data, dateString) => {
+                    set_computeDate(dateString);
+                    set_tableDataFilterParams({
+                      ...tableDataFilterParams,
+                      computeDate: dateString,
+                    });
+                  }}
+                  picker="month"
+                  locale={locale}
+                  defaultValue={moment(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`, 'YYYY-MM')}
+                  format="YYYY-MM"
+                  placeholder="选择年月"
+                />
+              </div>
+            }
+          </div>
+          <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
+            <span className='label' style={{ whiteSpace: 'nowrap' }}> 检索:</span>
+            <Input placeholder={'人事分类'} allowClear
+              suffix={
+                <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('filter')} />
+              }
+              onChange={(e) => {
+                set_tableDataSearchKeywords(e.target.value);
+                if (e.target.value.length == 0) {
+                  set_tableDataFilterParams({
+                    ...tableDataFilterParams,
+                    filter: ''
+                  });
+                }
+              }}
+              onPressEnter={(e) => {
+                set_tableDataFilterParams({
+                  ...tableDataFilterParams,
+                  filter: ((e.target) as HTMLInputElement).value
+                });
+              }}
+
+            />
+          </div>
+        </div>
+        <div className="btnGroup">
+          <a className='calc' onClick={() => calcFunc()}>计算</a>
+        </div>
+      </div>
+      <div style={{ marginTop: 16 }}>
+        <KCIMTable
+          columns={columns}
+          actionRef={tableRef}
+          rowKey="id"
+
+          params={tableDataFilterParams}
+          request={(params) => getTableData(params)}
+        />
+      </div>
+    </KCIMPagecontainer>
+  );
+}

+ 41 - 0
src/pages/costAccounting/unitPersonnelCostCalc/service.js

@@ -0,0 +1,41 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-10-26 16:30:43
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export const getData = (params) => {
+  return request('/costAccount/calculate/empCostCalculateList', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+//计算
+export const calculateReq = (computeDate) => {
+  return request('/costAccount/calculate/empCostCalculate', {
+    method: 'POST',
+    params:{computeDate}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+
+

+ 47 - 0
src/pages/costAccounting/unitPersonnelCostCalc/style.less

@@ -0,0 +1,47 @@
+
+
+.unitPersonnelCostCalc {
+  position: relative;
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      
+      .calc {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 358 - 0
src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/index.tsx

@@ -0,0 +1,358 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:22:08
+ * @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 { formatMoneyNumber } from '@/utils/format';
+import { createFromIconfontCN } from '@ant-design/icons';
+import FormItem from 'antd/es/form/FormItem';
+
+import { ActionType, ProFormDatePicker, ProFormDateTimePicker, ProFormInstance, ProFormText } from '@ant-design/pro-components';
+import { ModalForm, ProFormDependency, ProFormDigit, ProFormRadio, ProFormSelect, ProFormSwitch } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Popconfirm, Form } from 'antd';
+import { Fragment, useEffect, useRef, useState } from 'react';
+
+import 'moment/locale/zh-cn';
+import locale from 'antd/es/date-picker/locale/zh_CN';
+
+
+
+import { addData, delData, editData, getDrugTableData, getDrugTypeReq, importDataPost } from './service';
+
+import './style.less';
+import KCIMUpload from '@/components/KCIMUpload';
+import { downloadTemplateReq } from '@/utils/tooljs';
+
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+export default function DrugCostManagement() {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const tableRef = useRef<ActionType>();
+    const formRef = useRef<ProFormInstance>();
+
+    const columns: ProColumns[] = [
+
+        {
+            title: '项目代码',
+            dataIndex: 'code',
+        },
+        {
+            title: '项目名称',
+            dataIndex: 'name',
+        },
+        {
+            title: '项目类型',
+            dataIndex: 'type',
+        },
+        {
+            title: '单价',
+            dataIndex: 'price',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '成本',
+            dataIndex: 'cost',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '停用',
+            dataIndex: 'status',
+            renderText(stat) {
+                return stat ? '是' : '否'
+            },
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                return [
+                    <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+
+    ]
+
+
+    const getTableData = async (params: any) => {
+        const resp = await getDrugTableData(params);
+        if (resp) {
+            return {
+                data: 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 updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
+
+        const result = {
+            ...formVal
+        }
+
+        if (type == 'ADD') {
+            const resp = await addData(result);
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+
+        }
+        if (type == 'EDIT') {
+
+            const resp = await editData({...result});
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+        }
+        return true;
+
+    }
+
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
+
+        return (
+            <ModalForm
+                title={`${type == 'EDIT' ? '编辑' : '新增'}药品`}
+                width={350}
+                formRef={formRef}
+                initialValues={type == 'EDIT' ? {
+                    ...record,
+                } : {status:0}}
+                trigger={
+                    type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT' ? { ...record, ...val } : { ...val }, type);
+                }}
+                modalProps={{ destroyOnClose: true }}
+                colProps={{ span: 24 }}
+                grid
+            >
+                <ProFormText
+                    name="code"
+                    label="项目代码:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目代码不能为空!' }]}
+                />
+                <ProFormText
+                    name="name"
+                    label="项目名称:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目名称不能为空!' }]}
+                />
+                <ProFormSelect
+                    name="type"
+                    label="项目类型:"
+                    placeholder="请选择"
+                    request={async () => {
+                        const resp = await getDrugTypeReq();
+                        if(resp){
+                              return resp.map((a:any)=>({label:a.name,value:a.code}))
+                        }
+                    }}
+                    rules={[{ required: true, message: '项目类型不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="price"
+                    label="单价:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '单价不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="cost"
+                    label="成本:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '成本不能为空!' }]}
+                />
+                <Form.Item style={{ width: 322 }} label={<span style={{}}><i style={{ fontSize: 14, color: '#FF4060', fontWeight: 400, position: 'relative', paddingRight: 4, paddingLeft: 4 }}>*</i>停用:</span>}>
+                    <div style={{ display: 'flex', flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
+                        <ProFormRadio.Group
+                            name="status"
+                            noStyle
+                            colProps={{ span: 10 }}
+                            options={[
+                                {
+                                    label: '否',
+                                    value: 0
+                                },
+                                {
+                                    label: '是',
+                                    value: 1
+                                }
+                            ]}
+                        />
+                        {/* style={{position:'relative',left:-10}}  */}
+                        <ProFormDependency name={['status']}>
+                            {
+                                ({ status }) => {
+                                    // console.log({report});
+                                    return (
+
+                                        status ? <ProFormDateTimePicker fieldProps={{locale}} name="stopTime" colProps={{ span: 14 }} noStyle  />:null
+                                    )
+                                }
+                            }
+                        </ProFormDependency>
+
+                    </div>
+                </Form.Item>
+
+
+            </ModalForm>
+        )
+    }
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+
+    }
+
+    const downloadTemplate = async () => {
+        await downloadTemplateReq('/costAccount/setting/exportDrug');
+    };
+    
+      const importData = () => {
+        return (
+          <ModalForm
+            width={360}
+            title={`导入数据`}
+            trigger={
+              <a className="import" key="3">
+                导入
+              </a>
+            }
+            submitter={{
+              render: (props, defaultDoms) => {
+                const needBtn = defaultDoms.filter((b) => {
+                  return b.key != 'rest';
+                });
+                return [
+                  // <Button
+                  //     key="ok"
+                  //     onClick={auditType == '0' ? () => downloadTemplate(index) : () => { }}
+                  // >
+                  //     下载模板
+                  // </Button>,
+                  ...needBtn,
+                ];
+              },
+            }}
+            onFinish={async (values) => {
+              const {
+                importFile: { fileList },
+              } = values;
+    
+              let formData = new FormData();
+              formData.append('file', fileList[0].originFileObj);
+              const resp = await importDataPost(formData);
+    
+              if (resp) {
+                tableRef.current?.reload();
+                return true;
+              }
+            }}
+          >
+            <FormItem name={'importFile'}>
+              <KCIMUpload downloadTemplateFile={() => downloadTemplate()} />
+            </FormItem>
+          </ModalForm>
+        );
+      };
+
+
+    useEffect(() => {
+
+    }, [])
+
+    return (
+        <KCIMPagecontainer className='DrugCostManagement' title={false}>
+            <div className='toolBar'>
+                <div className='filter'>
+                    <div className='filterItem'>
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 项目名称:</span>
+                        <Input placeholder={'请输入'} allowClear
+                            suffix={
+                                <IconFont type="iconsousuo" onClick={() => tableDataSearchHandle('name')} />
+                            }
+                            onChange={(e) => {
+                                set_tableDataSearchKeywords(e.target.value);
+                                if (e.target.value.length == 0) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        name: ''
+                                    });
+                                }
+                            }}
+                            onPressEnter={(e) => {
+
+                                set_tableDataFilterParams({
+                                    ...tableDataFilterParams,
+                                    name: (e.target as HTMLInputElement).value
+                                });
+                            }}
+
+                        />
+                    </div>
+                </div>
+                <div className='btnGroup'>
+                    <span style={{paddingRight:16}}><ProFormSwitch noStyle fieldProps={{size:'small',onChange:(bool)=>{set_tableDataFilterParams({...tableDataFilterParams,stop:bool?1:0})}}} /> 显示停用项目</span>
+                    {importData()}
+                    <UpDataActBtn record type='ADD' />
+                </div>
+            </div>
+
+            <div style={{ marginTop: 16 }}>
+                <KCIMTable columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
+            </div>
+        </KCIMPagecontainer>
+    )
+}

+ 110 - 0
src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/service.ts

@@ -0,0 +1,110 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:17:15
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export type DrugTableDataType = {
+  id:number,
+  hospId:number,
+  code:number,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+
+export const getDrugTableData = (params?:any) => {
+  return request<{
+       current:number;
+       list:DrugTableDataType[];
+       pageSize:number;
+       totalCount:number;
+       totalPage:number;
+  }>('/costAccount/setting/getDrugList', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+//获取药品类型
+export const getDrugTypeReq = () => {
+  return request('/costAccount/setting/getDrugType', {
+    method: 'GET',
+  });
+};
+
+
+
+//新增
+export type AddTableDataType = {
+  code:string,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+export const addData = (data:AddTableDataType) => {
+  return request('/costAccount/setting/addDrug', {
+    method: 'POST',
+    data
+  });
+};
+
+
+//导入数据
+export const importDataPost = (data:any) => {
+  return request('/costAccount/setting/importDrug', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+//编辑表格数据
+
+export type TableRowEditType = {
+  id:number;
+}&AddTableDataType
+
+export const editData = (data:any) => {
+  return request('/costAccount/setting/editDrug', {
+    method: 'POST',
+    data
+  });
+};
+
+//删除表格操作
+export const delData = (id:string) => {
+  return request('/costAccount/setting/deleteDrug', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+

+ 55 - 0
src/pages/costLibraryManagement/basicCostManagement/drugCostManagement/style.less

@@ -0,0 +1,55 @@
+.DrugCostManagement {
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      .import {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #17181A;
+        line-height: 24px;
+        padding: 0 14px;
+        margin-right: 8px;
+        background: #FAFCFF;
+        border-radius: 4px;
+        border: 1px solid #DAE2F2;
+      }
+      .add {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 370 - 0
src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/index.tsx

@@ -0,0 +1,370 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:00:35
+ * @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 { formatMoneyNumber } from '@/utils/format';
+import { createFromIconfontCN } from '@ant-design/icons';
+import FormItem from 'antd/es/form/FormItem';
+
+import { ActionType, ProFormDateTimePicker, ProFormInstance, ProFormText } from '@ant-design/pro-components';
+import { ModalForm, ProFormDependency, ProFormDigit, ProFormRadio, ProFormSelect, ProFormSwitch } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Popconfirm, Form } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import 'moment/locale/zh-cn';
+import locale from 'antd/es/date-picker/locale/zh_CN';
+
+
+
+import { addData, delData, editData, getEquipTableData, importDataPost } from './service';
+
+import './style.less';
+import KCIMUpload from '@/components/KCIMUpload';
+import { downloadTemplateReq } from '@/utils/tooljs';
+
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+export default function EquipmentCostManagement() {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const tableRef = useRef<ActionType>();
+    const formRef = useRef<ProFormInstance>();
+
+    const columns: ProColumns[] = [
+
+        {
+            title: '设备编码',
+            dataIndex: 'code',
+        },
+        {
+            title: '项目名称',
+            dataIndex: 'name',
+        },
+        {
+            title: '设备型号',
+            dataIndex: 'type',
+        },
+        {
+            title: '折旧年限',
+            dataIndex: 'depreciationYear',
+        },
+        {
+            title: '采购价格(元)',
+            dataIndex: 'price',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '每年折旧',
+            dataIndex: 'costPerYear',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '每分钟成本',
+            dataIndex: 'costPerMinute',
+        },
+        {
+            title: '停用',
+            dataIndex: 'status',
+            renderText(num) {
+                return num?'是':'否'
+            },
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                return [
+                    <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+
+    ]
+
+
+    const getTableData = async (params: any) => {
+        const resp = await getEquipTableData(params);
+        if (resp) {
+            return {
+                data: 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 updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
+
+        const result = {
+            ...formVal
+        }
+
+        if (type == 'ADD') {
+            const resp = await addData(result);
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+
+        }
+        if (type == 'EDIT') {
+
+            const resp = await editData({...result});
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+        }
+        return true;
+
+    }
+
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
+
+        return (
+            <ModalForm
+                title={`${type == 'EDIT' ? '编辑' : '新增'}药品`}
+                width={350}
+                formRef={formRef}
+                initialValues={type == 'EDIT' ? {
+                    ...record,
+                } : {status:0}}
+                trigger={
+                    type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT' ? { ...record, ...val } : { ...val }, type);
+                }}
+                modalProps={{ destroyOnClose: true }}
+                colProps={{ span: 24 }}
+                grid
+            >
+                <ProFormText
+                    name="code"
+                    label="项目代码:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目代码不能为空!' }]}
+                />
+                <ProFormText
+                    name="name"
+                    label="项目名称:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目名称不能为空!' }]}
+                />
+                <ProFormSelect
+                    name="type"
+                    label="项目类型:"
+                    placeholder="请选择"
+                    options={[
+                        {
+                            label:'不计价材料',
+                            value:'不计价材料'
+                        },
+                        {
+                            label:'高值材料',
+                            value:'不计价材料'
+                        }
+                    ]}
+                    rules={[{ required: true, message: '项目类型不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="price"
+                    label="单价:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '单价不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="cost"
+                    label="成本:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '成本不能为空!' }]}
+                />
+                <Form.Item style={{ width: 322 }} label={<span style={{}}><i style={{ fontSize: 14, color: '#FF4060', fontWeight: 400, position: 'relative', paddingRight: 4, paddingLeft: 4 }}>*</i>停用:</span>}>
+                    <div style={{ display: 'flex', flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
+                        <ProFormRadio.Group
+                            name="status"
+                            noStyle
+                            colProps={{ span: 10 }}
+                            options={[
+                                {
+                                    label: '否',
+                                    value: 0
+                                },
+                                {
+                                    label: '是',
+                                    value: 1
+                                }
+                            ]}
+                        />
+                        {/* style={{position:'relative',left:-10}}  */}
+                        <ProFormDependency name={['status']}>
+                            {
+                                ({ status }) => {
+                                    // console.log({report});
+                                    return (
+
+                                        status ? <ProFormDateTimePicker fieldProps={{locale}} name="stopTime" colProps={{ span: 14 }} noStyle  />:null
+                                    )
+                                }
+                            }
+                        </ProFormDependency>
+
+                    </div>
+                </Form.Item>
+
+
+            </ModalForm>
+        )
+    }
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+
+    }
+
+    const downloadTemplate = async () => {
+        await downloadTemplateReq('/costAccount/setting/exportEquipment');
+    };
+    
+      const importData = () => {
+        return (
+          <ModalForm
+            width={360}
+            title={`导入数据`}
+            trigger={
+              <a className="import" key="3">
+                导入
+              </a>
+            }
+            submitter={{
+              render: (props, defaultDoms) => {
+                const needBtn = defaultDoms.filter((b) => {
+                  return b.key != 'rest';
+                });
+                return [
+                  // <Button
+                  //     key="ok"
+                  //     onClick={auditType == '0' ? () => downloadTemplate(index) : () => { }}
+                  // >
+                  //     下载模板
+                  // </Button>,
+                  ...needBtn,
+                ];
+              },
+            }}
+            onFinish={async (values) => {
+              const {
+                importFile: { fileList },
+              } = values;
+    
+              let formData = new FormData();
+              formData.append('file', fileList[0].originFileObj);
+              const resp = await importDataPost(formData);
+    
+              if (resp) {
+                tableRef.current?.reload();
+                return true;
+              }
+            }}
+          >
+            <FormItem name={'importFile'}>
+              <KCIMUpload downloadTemplateFile={() => downloadTemplate()} />
+            </FormItem>
+          </ModalForm>
+        );
+      };
+
+
+    useEffect(() => {
+
+    }, [])
+
+    return (
+        <KCIMPagecontainer className='EquipmentCostManagement' title={false}>
+            <div className='toolBar'>
+                <div className='filter'>
+                    <div className='filterItem'>
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 设备名称:</span>
+                        <Input placeholder={'请输入'} allowClear
+                            suffix={
+                                <IconFont type="iconsousuo" onClick={() => tableDataSearchHandle('name')} />
+                            }
+                            onChange={(e) => {
+                                set_tableDataSearchKeywords(e.target.value);
+                                if (e.target.value.length == 0) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        name: ''
+                                    });
+                                }
+                            }}
+                            onPressEnter={(e) => {
+
+                                set_tableDataFilterParams({
+                                    ...tableDataFilterParams,
+                                    name: (e.target as HTMLInputElement).value
+                                });
+                            }}
+
+                        />
+                    </div>
+                </div>
+                <div className='btnGroup'>
+                    <span style={{paddingRight:16}}><ProFormSwitch noStyle fieldProps={{size:'small',onChange:(bool)=>{set_tableDataFilterParams({...tableDataFilterParams,stop:bool?1:0})}}} /> 显示停用项目</span>
+                    {importData()}
+                    <UpDataActBtn record type='ADD' />
+                </div>
+            </div>
+
+            <div style={{ marginTop: 16 }}>
+                <KCIMTable columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
+            </div>
+        </KCIMPagecontainer>
+    )
+}

+ 102 - 0
src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/service.ts

@@ -0,0 +1,102 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-07 18:45:24
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export type EquipTableDataType = {
+  id:number,
+  hospId:number,
+  code:number,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+
+export const getEquipTableData = (params?:any) => {
+  return request<{
+       current:number;
+       list:EquipTableDataType[];
+       pageSize:number;
+       totalCount:number;
+       totalPage:number;
+  }>('/costAccount/setting/getEquipmentList?', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+
+//新增
+export type AddTableDataType = {
+  code:string,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+export const addData = (data:AddTableDataType) => {
+  return request('/costAccount/setting/addEquipment', {
+    method: 'POST',
+    data
+  });
+};
+
+
+//导入数据
+export const importDataPost = (data:any) => {
+  return request('/costAccount/setting/importEquipment', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+//编辑表格数据
+
+export type TableRowEditType = {
+  id:number;
+}&AddTableDataType
+
+export const editData = (data:any) => {
+  return request('/costAccount/setting/editEquipment', {
+    method: 'POST',
+    data
+  });
+};
+
+//删除表格操作
+export const delData = (id:string) => {
+  return request('/costAccount/setting/deleteEquipment', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+

+ 55 - 0
src/pages/costLibraryManagement/basicCostManagement/equipmentCostManagement/style.less

@@ -0,0 +1,55 @@
+.EquipmentCostManagement {
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      .import {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #17181A;
+        line-height: 24px;
+        padding: 0 14px;
+        margin-right: 8px;
+        background: #FAFCFF;
+        border-radius: 4px;
+        border: 1px solid #DAE2F2;
+      }
+      .add {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 388 - 0
src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/index.tsx

@@ -0,0 +1,388 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:42:54
+ * @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 { formatMoneyNumber } from '@/utils/format';
+import { createFromIconfontCN } from '@ant-design/icons';
+import FormItem from 'antd/es/form/FormItem';
+
+import { ActionType, ProFormDateTimePicker, ProFormInstance, ProFormText } from '@ant-design/pro-components';
+import { ModalForm, ProFormDependency, ProFormDigit, ProFormRadio, ProFormSelect, ProFormSwitch } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Popconfirm, Form } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+import 'moment/locale/zh-cn';
+import locale from 'antd/es/date-picker/locale/zh_CN';
+
+
+
+import { addData, delData, editData, getDrugTableData, importDataPost } from './service';
+
+import './style.less';
+import KCIMUpload from '@/components/KCIMUpload';
+import { downloadTemplateReq } from '@/utils/tooljs';
+
+
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+export default function MaterialCostManagement() {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const tableRef = useRef<ActionType>();
+    const formRef = useRef<ProFormInstance>();
+    const [stopStat,set_stopStat] = useState(0);
+
+    const columns: ProColumns[] = [
+
+        {
+            title: '项目代码',
+            dataIndex: 'code',
+        },
+        {
+            title: '项目名称',
+            dataIndex: 'name',
+        },
+        {
+            title: '项目类型',
+            dataIndex: 'type',
+            renderText(num) {
+                return num == 1?'不计价材料':'高值材料'
+            },
+        },
+        {
+            title: '单价',
+            dataIndex: 'price',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '成本',
+            dataIndex: 'cost',
+            renderText(num) {
+                return formatMoneyNumber(num)
+            },
+        },
+        {
+            title: '停用',
+            dataIndex: 'status',
+            renderText(stat) {
+                return stat ? '是' : '否'
+            },
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                return [
+                    <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+
+    ]
+
+
+    const getTableData = async (params: any) => {
+        const resp = await getDrugTableData({...params,stop:stopStat});
+        if (resp) {
+            return {
+                data: 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 updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
+
+        const result = {
+            ...formVal
+        }
+
+        if (type == 'ADD') {
+            const resp = await addData(result);
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+
+        }
+        if (type == 'EDIT') {
+
+            const resp = await editData({ ...result });
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+        }
+        return true;
+
+    }
+
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
+
+        return (
+            <ModalForm
+                title={`${type == 'EDIT' ? '编辑' : '新增'}药品`}
+                width={350}
+                formRef={formRef}
+                initialValues={type == 'EDIT' ? {
+                    ...record,
+                } : { status: 0 }}
+                trigger={
+                    type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT' ? { ...record, ...val } : { ...val }, type);
+                }}
+                modalProps={{ destroyOnClose: true }}
+                colProps={{ span: 24 }}
+                grid
+            >
+                <ProFormText
+                    name="code"
+                    label="项目代码:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目代码不能为空!' }]}
+                />
+                <ProFormText
+                    name="name"
+                    label="项目名称:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '项目名称不能为空!' }]}
+                />
+                <ProFormSelect
+                    name="type"
+                    label="项目类型:"
+                    placeholder="请选择"
+                    options={[
+                        {
+                            label: '不计价材料',
+                            value: 1
+                        },
+                        {
+                            label: '高值材料',
+                            value: 2
+                        }
+                    ]}
+                    rules={[{ required: true, message: '项目类型不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="price"
+                    label="单价:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '单价不能为空!' }]}
+                />
+                <ProFormDigit
+                    name="cost"
+                    label="成本:"
+                    placeholder="请输入"
+                    rules={[{ required: true, message: '成本不能为空!' }]}
+                />
+                <Form.Item style={{ width: 322 }} label={<span style={{}}><i style={{ fontSize: 14, color: '#FF4060', fontWeight: 400, position: 'relative', paddingRight: 4, paddingLeft: 4 }}>*</i>停用:</span>}>
+                    <div style={{ display: 'flex', flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
+                        <ProFormRadio.Group
+                            name="status"
+                            noStyle
+                            colProps={{ span: 10 }}
+                            options={[
+                                {
+                                    label: '否',
+                                    value: 0
+                                },
+                                {
+                                    label: '是',
+                                    value: 1
+                                }
+                            ]}
+                        />
+                        {/* style={{position:'relative',left:-10}}  */}
+                        <ProFormDependency name={['status']}>
+                            {
+                                ({ status }) => {
+                                    // console.log({report});
+                                    return (
+
+                                        status ? <ProFormDateTimePicker fieldProps={{ locale }} name="stopTime" colProps={{ span: 14 }} rules={[{ required: true, message: '时间不能为空!' }]} noStyle /> : null
+                                    )
+                                }
+                            }
+                        </ProFormDependency>
+
+                    </div>
+                </Form.Item>
+
+
+            </ModalForm>
+        )
+    }
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+
+    }
+
+    const downloadTemplate = async () => {
+        await downloadTemplateReq('/costAccount/setting/exportMaterial');
+    };
+
+    const importData = () => {
+        return (
+            <ModalForm
+                width={360}
+                title={`导入数据`}
+                trigger={
+                    <a className="import" key="3">
+                        导入
+                    </a>
+                }
+                submitter={{
+                    render: (props, defaultDoms) => {
+                        const needBtn = defaultDoms.filter((b) => {
+                            return b.key != 'rest';
+                        });
+                        return [
+                            // <Button
+                            //     key="ok"
+                            //     onClick={auditType == '0' ? () => downloadTemplate(index) : () => { }}
+                            // >
+                            //     下载模板
+                            // </Button>,
+                            ...needBtn,
+                        ];
+                    },
+                }}
+                onFinish={async (values) => {
+                    const {
+                        importFile: { fileList },
+                    } = values;
+
+                    let formData = new FormData();
+                    formData.append('file', fileList[0].originFileObj);
+                    const resp = await importDataPost(formData);
+
+                    if (resp) {
+                        tableRef.current?.reload();
+                        return true;
+                    }
+                }}
+            >
+                <FormItem name={'importFile'}>
+                    <KCIMUpload downloadTemplateFile={() => downloadTemplate()} />
+                </FormItem>
+            </ModalForm>
+        );
+    };
+
+
+    useEffect(() => {
+
+    }, [])
+
+    return (
+        <KCIMPagecontainer className='MaterialCostManagement' title={false}>
+            <div className='toolBar'>
+                <div className='filter'>
+                    <div className='filterItem' style={{marginRight:16}} >
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 项目类型:</span>
+                        <ProFormSelect noStyle placeholder={'请选择类型'}
+                            width={160}
+                            options={[
+                                {label:'不计价材料',value:1},
+                                {label:'高值材料',value:2}
+                            ]}
+                            fieldProps={{
+                                onChange(value, option) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        itemType: value
+                                    });
+                                },
+                            }}
+                        />
+                    </div>
+                    <div className='filterItem'>
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 项目名称:</span>
+                        <Input placeholder={'请输入'} allowClear
+                            suffix={
+                                <IconFont type="iconsousuo" onClick={() => tableDataSearchHandle('name')} />
+                            }
+                            onChange={(e) => {
+                                set_tableDataSearchKeywords(e.target.value);
+                                if (e.target.value.length == 0) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        name: ''
+                                    });
+                                }
+                            }}
+                            onPressEnter={(e) => {
+
+                                set_tableDataFilterParams({
+                                    ...tableDataFilterParams,
+                                    name: (e.target as HTMLInputElement).value
+                                });
+                            }}
+
+                        />
+                    </div>
+                </div>
+                <div className='btnGroup'>
+                    <span style={{ paddingRight: 16 }}><ProFormSwitch noStyle fieldProps={{ size: 'small', onChange: (bool) => {
+                         set_stopStat(bool ? 1 : 0);
+                         tableRef.current?.reload();
+                     } }} /> 显示停用项目</span>
+                    {importData()}
+                    <UpDataActBtn record type='ADD' />
+                </div>
+            </div>
+
+            <div style={{ marginTop: 16 }}>
+                <KCIMTable columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
+            </div>
+        </KCIMPagecontainer>
+    )
+}

+ 102 - 0
src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/service.ts

@@ -0,0 +1,102 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-07 18:32:03
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export type MaterialTableDataType = {
+  id:number,
+  hospId:number,
+  code:number,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+
+export const getDrugTableData = (params?:any) => {
+  return request<{
+       current:number;
+       list:MaterialTableDataType[];
+       pageSize:number;
+       totalCount:number;
+       totalPage:number;
+  }>('/costAccount/setting/getMaterialList', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+
+//新增
+export type AddTableDataType = {
+  code:string,
+  name:string,
+  type:string,
+  price:number,
+  cost:number,
+  status:number,
+  stopTime:string
+}
+
+export const addData = (data:AddTableDataType) => {
+  return request('/costAccount/setting/addMaterial', {
+    method: 'POST',
+    data
+  });
+};
+
+
+//导入数据
+export const importDataPost = (data:any) => {
+  return request('/costAccount/setting/importMaterial', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+//编辑表格数据
+
+export type TableRowEditType = {
+  id:number;
+}&AddTableDataType
+
+export const editData = (data:any) => {
+  return request('/costAccount/setting/editMaterial', {
+    method: 'POST',
+    data
+  });
+};
+
+//删除表格操作
+export const delData = (id:string) => {
+  return request('/costAccount/setting/deleteMaterial', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+

+ 55 - 0
src/pages/costLibraryManagement/basicCostManagement/materialCostManagement/style.less

@@ -0,0 +1,55 @@
+.MaterialCostManagement {
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      .import {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #17181A;
+        line-height: 24px;
+        padding: 0 14px;
+        margin-right: 8px;
+        background: #FAFCFF;
+        border-radius: 4px;
+        border: 1px solid #DAE2F2;
+      }
+      .add {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 532 - 0
src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/index.tsx

@@ -0,0 +1,532 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:14:36
+ * @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 { ActionType, arrayMoveImmutable, ProFormInstance, useRefFunction } from '@ant-design/pro-components';
+import { ModalForm, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
+import { ProColumns } from '@ant-design/pro-table';
+import { Dropdown, Input, MenuProps, message, Modal, Switch, Tooltip, Popconfirm } from 'antd';
+import { ColumnsType } from 'antd/es/table/interface';
+import { TransferItem, TransferProps } from 'antd/es/transfer';
+import { Key } from 'react';
+import { useEffect, useRef, useState } from 'react';
+
+
+import { getLeftList, getClolumnTableData, addLeftList, editLeftList, editReportTbaleData, delLeftReportData, batchDelTableData, addReportTbaleData, delData, getEmpCostTypeDict, updateEmpInfo } from './service';
+
+
+import './style.less';
+
+
+import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
+
+import '../../../../utils/zhongtaiB'
+import KCIMPagecontainer from '@/components/KCIMPageContainer';
+import { KCIMTable } from '@/components/KCIMTable';
+
+import TableSelecter from './tableSelector';
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+var temp_dataSource: any[] = [];
+let _currentSelectedType: any = undefined;
+
+const PersonnelClassificationMana = () => {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const [selectedRowKeys, set_selectedRowKeys] = useState<Key[]>([]);
+    const [typeList, set_typeList] = useState<any[]>([]);
+    const [showTypeListArr, set_showTypeListArr] = useState<any[]>([]);
+    const [currentSelectedType, set_currentSelectedType] = useState<any | undefined>(undefined);
+
+
+    const [tableSelecterVisible, set_tableSelecterVisible] = useState(false);
+    const [dataSource, setDataSource] = useState<any[]>([]);
+    const SortableItem = SortableElement((props: any) => <tr {...props} />);
+    const SortContainer = SortableContainer((props: any) => <tbody {...props} />);
+
+    const [currentEditLeftData, set_currentEditLeftData] = useState<any | undefined>(undefined);
+
+    const [ifEditTable, set_ifEditTable] = useState(true);
+
+    const tableRef = useRef<ActionType>();
+
+    const DragHandle = SortableHandle(() => <img width={16} style={{ cursor: 'pointer' }} src={require('../../../../../static/tuozhuai_icon.png')} alt="" />);
+
+    const column: ProColumns[] = [
+
+        {
+            title: '工号',
+            ellipsis: true,
+            dataIndex: 'account',
+
+        },
+        {
+            title: '姓名',
+            dataIndex: 'name',
+
+        },
+        {
+            title: '科室代码',
+            dataIndex: 'departmentCode',
+        },
+        {
+            title: '岗位',
+            dataIndex: 'positionName',
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+
+                return [
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record.id)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+    ]
+
+    const [tableColumn, set_tableColumn] = useState<ProColumns[] | any[]>(column);
+
+
+
+
+    const getTableData = async (params: any) => {
+        console.log({ params });
+        const { costTypeCode } = params;
+        if (costTypeCode) {
+            const resp = await getClolumnTableData({ ...params });
+            if (resp) {
+                return {
+                    data: resp.list,
+                    success: true,
+                    total: resp.totalCount,
+                    pageSize: resp.pageSize,
+                    totalPage: resp.totalPage,
+                }
+            }
+
+        }
+        return []
+
+    }
+
+
+    //获取左侧单元
+    const getPageLeftReports = async () => {
+        const resp = await getLeftList();
+
+        if (resp) {
+
+            set_typeList(resp);
+            set_showTypeListArr(resp);
+        }
+    }
+
+    const delTableData = async (id: number) => {
+        const resp = await delData(id);
+        if (resp) {
+            message.success('操作成功!');
+            tableRef.current?.reload();
+        }
+    }
+
+    const batchDelHandle = async () => {
+        const resp = await batchDelTableData(selectedRowKeys);
+        if (resp) {
+            message.success('操作成功!');
+            set_selectedRowKeys([]);
+            tableRef.current?.reload();
+        }
+    }
+
+    const tableSelecterCommit = async (keys: Key[], rows: any[]) => {
+        const result = rows.map((a, index) => ({
+            costTypeCode: _currentSelectedType.costTypeCode,
+            userId: a.id,
+            account: a.account,
+            name: a.name,
+            departmentCode:a.departmentCode,
+            departmentName:a.departmentName,
+            position:a.position,
+            positionName:a.positionName
+        }))
+        const resp = await addReportTbaleData(result);
+        if (resp) {
+            message.success('操作成功');
+            set_tableSelecterVisible(false);
+            tableRef.current?.reload();
+        }
+    }
+
+
+    const updateTable = async (formVal: any, type: 'EDIT' | "ADD" | 'ADD_LEFTDATA' | 'EDIT_LEFTDATA', data?: any[]) => {
+
+        // console.log({formVal,type});
+
+        if (type == 'ADD_LEFTDATA') {
+            const resp = await addLeftList({
+                //costTypeCode: formVal.costTypeCode,
+                costTypeName: formVal.costTypeName,
+                computeType: formVal.computeType.value,
+                computeTypeName: formVal.computeType.label,
+                description: formVal.description
+            });
+            if (resp) {
+                getPageLeftReports();
+            }
+        }
+
+
+
+        if (type == 'EDIT_LEFTDATA') {
+            const resp = await editLeftList({
+                id: formVal.id,
+                costTypeName: formVal.costTypeName,
+                computeType: formVal.computeType.value,
+                computeTypeName: formVal.computeType.label,
+                description: formVal.description
+            });
+            if (resp) {
+                getPageLeftReports();
+            }
+        }
+
+        if (type == 'EDIT') {
+
+            let newDataSource = data?.map((a: any, index: number) => {
+                //更新排序
+                return { ...a, sort: index + 1 }
+            })
+            const resp = await editReportTbaleData(newDataSource);
+            if (resp) {
+                tableRef.current?.reload();
+            }
+        }
+
+        return true;
+
+    }
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' | 'ADD_LEFTDATA' | 'EDIT_LEFTDATA' }) => {
+        const formRef = useRef<ProFormInstance>();
+        const getTrriger = () => {
+            if (type == 'ADD') {
+                return <span className='add'>新增</span>
+            }
+            if (type == 'EDIT') {
+                return <a key="edit" >编辑</a>
+            }
+            if (type == 'ADD_LEFTDATA') {
+                return (
+                    <div className='add'>
+                        <img src={require('../../../../../static/addIcon_black.png')} alt="" />
+                    </div>
+                )
+            }
+            if (type == 'EDIT_LEFTDATA') {
+                return <a key="edit" >编辑</a>
+            }
+        }
+
+        return (
+            <ModalForm
+                formRef={formRef}
+                title={type == 'ADD_LEFTDATA' ? `新增人事分类` : `编辑人事分类`}
+                width={352}
+                initialValues={type == 'EDIT_LEFTDATA' ? { ...record } : { computeTypeName: '' }}
+                trigger={
+                    getTrriger()
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT_LEFTDATA' ? { ...record, ...val } : val, type);
+                }}
+            >
+
+                <ProFormText
+                    label='人事分类名称:'
+                    name='costTypeName'
+                    rules={[{ required: true, message: '人事分类名称不能为空!' }]}
+                />
+                {/* <ProFormText
+                    label='人事分类代码:'
+                    name='costTypeCode'
+                    rules={[{ required: true, message: '人事分类代码不能为空!' }]}
+                /> */}
+                <ProFormSelect
+                    name="computeType"
+                    label="子级类型:"
+                    placeholder="请选择"
+                    request={async () => {
+                        const resp = await getEmpCostTypeDict();
+                        if (resp) {
+                            return resp.map((a: any) => ({ label: a.name, value: a.code }));
+                        }
+                        return []
+                    }}
+                    fieldProps={{
+                        labelInValue: true,
+                        onChange(value, option: any) {
+                            // console.log({value,option})
+                            // const {label} = option;
+                            // console.log({label});
+                            // formRef.current?.setFieldValue('computeTypeName',label);
+                        },
+                    }}
+                    rules={[{ required: true, message: '子集类型不能为空!' }]}
+                />
+                <ProFormTextArea
+                    label='说明:'
+                    name='description'
+                />
+            </ModalForm>
+        )
+    }
+
+
+    const moreItems: MenuProps['items'] = [
+        {
+            key: '1',
+            label: <UpDataActBtn key={'act'} record={currentEditLeftData} type='EDIT_LEFTDATA' />,
+        },
+        {
+            key: '2',
+            label: (
+                <a onClick={async (e) => {
+                    e.preventDefault();
+                    const resp = await delLeftReportData(currentEditLeftData.id);
+                    if (resp) {
+                        getPageLeftReports();
+                    }
+                }}>
+                    删除
+                </a>
+            ),
+        },
+        {
+            key: '3',
+            label: (<a onClick={async (e) => {
+                e.preventDefault();
+                // 选取要复制的文本
+                const textToCopy = currentEditLeftData.code;
+
+                // 创建一个临时的textarea元素
+                const tempTextArea = document.createElement("textarea");
+                tempTextArea.value = textToCopy;
+                document.body.appendChild(tempTextArea);
+
+                // 选中并复制文本
+                tempTextArea.select();
+                document.execCommand("copy");
+
+                // 移除临时元素
+                document.body.removeChild(tempTextArea);
+                message.success('复制成功!');
+
+            }}>
+                复制报表code
+            </a>),
+        },
+    ];
+
+
+
+    const onSortEnd = useRefFunction(
+        ({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {
+            if (oldIndex !== newIndex) {
+                const newData = arrayMoveImmutable({
+                    array: [...dataSource],
+                    fromIndex: oldIndex,
+                    toIndex: newIndex,
+                }).filter((el) => !!el);
+
+                const updatedSortArr = newData.map((item: any, index: number) => ({ ...item, sort: index }))
+                // setDataSource([...updatedSortArr]);
+                updateTable(undefined, 'EDIT', updatedSortArr)
+            }
+        },
+    );
+
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+    }
+
+    const updateEmpInfoHandle = async () => {
+          const resp = await updateEmpInfo();
+          if(resp){
+            message.success('更新成功!');
+            tableRef.current?.reload();
+          }
+    }
+
+
+
+    useEffect(() => {
+
+        if (currentSelectedType) {
+            set_tableDataFilterParams({ ...tableDataFilterParams, costTypeCode: currentSelectedType.costTypeCode });
+        }
+    }, [currentSelectedType])
+
+    useEffect(() => {
+        if (showTypeListArr.length > 0) {
+            set_currentSelectedType(showTypeListArr[0]);
+            _currentSelectedType = showTypeListArr[0];
+            set_tableDataFilterParams({ ...tableDataFilterParams, costTypeCode: showTypeListArr[0].costTypeCode });
+        }
+    }, [showTypeListArr]);
+
+    useEffect(() => {
+        if (ifEditTable) {
+            set_tableColumn([...column])
+        } else {
+            set_tableColumn(column);
+        }
+    }, [ifEditTable]);
+
+
+    useEffect(() => {
+        getPageLeftReports();
+    }, [])
+
+
+    return (
+        <KCIMPagecontainer title={false} className='PersonnelClassificationMana'>
+            <TableSelecter
+                onVisibleChange={(bool) => set_tableSelecterVisible(bool)}
+                title='添加单元人员信息'
+                rowKey={'id'}
+                defaultSelectedKeys={[]}
+                record={_currentSelectedType}
+                open={tableSelecterVisible}
+                onFinish={(keys, rows) => tableSelecterCommit(keys, rows)}
+            />
+            {selectedRowKeys.length > 0 && (
+                <div className='bottomBar'>
+                    <span>已选择<a>{selectedRowKeys.length}</a>项</span>
+                    <a onClick={() => batchDelHandle()}>批量删除</a>
+                </div>
+            )}
+            <div className='left'>
+                <div className='toolbar'>
+                    <Input placeholder={'人事分类'} allowClear
+                        suffix={
+                            <IconFont type="iconsousuo" />
+                        }
+                        style={{ width: 156 }}
+                        onChange={(e) => {
+                            const result = typeList.filter(item => item.costTypeName.indexOf(e.target.value) != -1);
+                            set_showTypeListArr(result);
+                        }}
+
+                    />
+                    <UpDataActBtn key={'act'} record={undefined} type='ADD_LEFTDATA' />
+
+                </div>
+
+                <div className='wrap'>
+                    {
+                        showTypeListArr.map((item, index) => {
+                            return (
+                                <div className={currentSelectedType ? currentSelectedType.id == item.id ? 'type on' : 'type' : 'type'}
+                                    key={index}
+                                    onClick={() => {
+                                        set_currentSelectedType(item)
+                                        _currentSelectedType = item;
+                                    }}
+                                >
+                                    <img className='icon' src={require('../../../../../static/reportIcon.png')} alt="" />
+                                    <div className='content'>
+                                        <Tooltip title={item.costTypeName} >
+                                            <div className='name'>{item.costTypeName}</div>
+                                            <div className='sub'>{item.computeTypeName}</div>
+                                        </Tooltip>
+                                    </div>
+
+                                    <Dropdown menu={{ items: moreItems }} placement="bottom" onOpenChange={(bool) => { bool && set_currentEditLeftData(item) }}>
+                                        <div className='more'>
+                                            <img src={require('../../../../../static/more_point_gray.png')} alt="" />
+                                        </div>
+                                    </Dropdown>
+                                </div>
+                            )
+                        })
+                    }
+                </div>
+            </div>
+            <div className='right'>
+                <div className='toolBar'>
+                    <div className='filter'>
+                        <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
+                            <span className='label' style={{ whiteSpace: 'nowrap' }}> 检索:</span>
+                            <Input placeholder={'输入工号,姓名'} allowClear
+                                suffix={
+                                    <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('filter')} />
+                                }
+                                onChange={(e) => {
+                                    set_tableDataSearchKeywords(e.target.value);
+                                    if (e.target.value.length == 0) {
+                                        set_tableDataFilterParams({
+                                            ...tableDataFilterParams,
+                                            filter: ''
+                                        });
+                                    }
+                                }}
+                                onPressEnter={(e) => {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        filter: ((e.target) as HTMLInputElement).value
+                                    });
+                                }}
+
+                            />
+                        </div>
+                    </div>
+                    <div className='btnGroup'>
+                        <span className='update' onClick={() => updateEmpInfoHandle()}>更新人员信息</span>
+                        <span className='add' onClick={() => set_tableSelecterVisible(true)}>添加</span>
+                    </div>
+                </div>
+                <div style={{ marginTop: 16 }}>
+                    {currentSelectedType && <KCIMTable actionRef={tableRef} columns={tableColumn}
+                        rowKey='id'
+                        request={(params) => getTableData(params)}
+                        tableAlertRender={false}
+                        params={tableDataFilterParams}
+                        rowSelection={{
+                            onChange(selectedRowKeys, selectedRows, info) {
+                                set_selectedRowKeys(selectedRowKeys);
+                            },
+                        }}
+                    />}
+                </div>
+            </div>
+        </KCIMPagecontainer>
+    )
+}
+
+
+export default PersonnelClassificationMana;

+ 132 - 0
src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/service.ts

@@ -0,0 +1,132 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-07 11:12:10
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 16:06:26
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { Key } from 'react';
+import { request } from 'umi';
+
+
+//获取左侧报表数据
+
+export const getLeftList = () => {
+  return request('/costAccount/setting/getEmpCostType', {
+    method: 'GET',
+  });
+};
+
+//获取人事分类计算类型
+export const getEmpCostTypeDict = () => {
+  return request('/costAccount/setting/getEmpCostTypeDict', {
+    method: 'GET',
+  });
+};
+
+//获取表格数据
+
+export type  ClolumnTableDataType = {
+  id:number;
+  
+}
+
+export const getClolumnTableData = (params:{costTypeCode:string}) => {
+    return request('/costAccount/setting/getEmpCostMap', {
+      method: 'GET',
+      params:{...params}
+    });
+};
+
+//获取可添加列表
+export const getAddableTableData = (costType:string) => {
+  return request('/costAccount/setting/getEmpInfo', {
+    method: 'GET',
+    params:{costType}
+  });
+};
+
+
+//新增左侧列表
+
+
+export const addLeftList = (data:any) => {
+  return request('/costAccount/setting/addEmpCostType', {
+    method: 'POST',
+    data
+  });
+};
+
+
+//编辑左侧列表
+export const editLeftList= (data:any) => {
+  return request('/costAccount/setting/editEmpCostType', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+
+//新增表格数据
+
+export const addReportTbaleData = (data:any) => {
+  return request('/costAccount/setting/addEmpCostMap', {
+    method: 'POST',
+    data
+  });
+};
+
+//更新人员信息
+export const updateEmpInfo = () => {
+  return request('/costAccount/setting/updateEmpMap', {
+    method: 'POST',
+  });
+};
+
+
+
+
+//编辑表格数据
+
+export const editReportTbaleData = (data:any) => {
+    return request('/costAccount/report/editReportColumn', {
+      method: 'POST',
+      data
+    });
+};
+
+
+//删除表格操作
+export const delData = (id:number) => {
+    return request('/costAccount/setting/deleteEmpCostMap', {
+      method: 'POST',
+      params:{id}
+    });
+};
+
+//删除左侧报表
+export const delLeftReportData = (id:number) => {
+  return request('/costAccount/setting/deleteEmpCostType', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+//批量删除表格数据
+export const batchDelTableData = (ids:Key[]) => {
+  return request('/costAccount/setting/batchDeleteEmpCostMap', {
+    method: 'POST',
+    data:[...ids]
+  });
+};
+
+
+
+

+ 249 - 0
src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/style.less

@@ -0,0 +1,249 @@
+.row-dragging {
+
+  .cost-ant-table-cell {
+    width: 130px;
+  }
+}
+
+.TableSelecter {
+
+  .pfm-ant-modal-footer {
+    display: none !important;
+  }
+  
+  .footer {
+       display: flex;
+       flex-direction:row;
+       justify-content: flex-end;
+       margin-top: 15px;
+       span {
+           display: inline-block;
+           width: 56px;
+           height: 24px;  
+           font-size: 14px;
+           line-height: 23px;
+           text-align: center;
+           border-radius: 4px;
+           cursor: pointer;
+
+           &.ok {
+               color: #FFFFFF;
+               background:#3377FF;
+               margin-left: 8px;
+           }
+           &.cancel {
+               border: 1px solid #DAE2F2;
+           }
+       }
+
+  }
+}
+
+.PersonnelClassificationMana {
+  width: 100%;
+  height: calc(100vh - 48px);
+  position: relative;
+
+  .bottomBar {
+    position: absolute;
+    bottom: -16px;
+    left: -16px;
+    width:102.5%;
+    height: 48px;
+    display: flex;
+    padding: 0 16px;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    background: #FFFFFF;
+box-shadow: 0px -8px 16px 0px rgba(64,85,128,0.1);
+
+    &>span {
+      font-size: 14px;
+      font-weight: 400;
+      color: #17181A;
+    }
+
+    &>a {
+      width: 80px;
+      height: 24px;
+      line-height: 24px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #FFFFFF;
+      text-align: center;
+      background: #3377FF;
+      border-radius: 4px;
+    }
+  }
+
+  .left {
+    float: left;
+    border-radius: 4px;
+    width: 220px;
+    height: calc(100vh - 80px);
+    overflow: scroll;
+    margin-right: 16px;
+    padding: 16px 8px;
+    background: #FFFFFF;
+
+    .toolbar {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      align-items: center;
+      padding: 0 8px;
+
+      .add {
+        cursor: pointer;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 24px;
+        height: 24px;
+        background: #FAFCFF;
+        border-radius: 4px;
+        border: 1px solid #DAE2F2;
+
+        &>img {
+          width: 16px;
+          height: 16px;
+        }
+      }
+    }
+
+    .wrap {
+      margin-top: 16px;
+
+      .type {
+        cursor: pointer;
+        height: 56px;
+        border-radius: 4px;
+        background: #FFFFFF;
+        display: flex;
+        padding-left: 8px;
+        padding-right: 8px;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 4px;
+
+        .icon {
+          width: 25px;
+          height: 25px;
+        }
+
+        .content {
+          width: 80%;
+          padding-left: 7px;
+
+          .name {
+            height: 15px;
+            font-size: 14px;
+            font-family: SourceHanSansCN-Medium, SourceHanSansCN;
+            font-weight: 500;
+            color: #17181A;
+            line-height: 15px;
+            margin-bottom: 8px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+
+          .sub {
+            height: 13px;
+            font-size: 12px;
+            font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+            font-weight: 400;
+            color: #7A8599;
+            line-height: 13px;
+          }
+        }
+
+        .more {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          width: 16px;
+          height: 16px;
+          border-radius: 4px;
+          background: #FFFFFF;
+
+          &>img {
+            width: 100%;
+            height: 100%;
+          }
+        }
+
+        &.on {
+          font-weight: 500;
+          color: #17181A;
+          background: #F0F2F5;
+        }
+
+        &:last-child {
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
+
+  .right {
+    float: left;
+    width: calc(100% - 236px);
+    padding: 16px;
+    border-radius: 4px;
+    background: #FFFFFF;
+
+    .toolBar {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      align-items: center;
+
+      .filter {
+        display: flex;
+        flex-direction: row;
+        justify-content: flex-start;
+        align-items: center;
+
+        .filterItem {
+          display: flex;
+          flex-direction: row;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+
+      .btnGroup {
+        .add {
+          cursor: pointer;
+          display: inline-block;
+          font-size: 14px;
+          font-weight: 400;
+          color: #FFFFFF;
+          line-height: 24px;
+          padding: 0 14px;
+          background: #3377FF;
+          border-radius: 4px;
+          margin-left: 8px;
+        }
+        .update {
+          cursor: pointer;
+          display: inline-block;
+          font-size: 14px;
+          font-weight: 400;
+          color: #17181A;
+          line-height: 24px;
+          padding: 0 14px;
+          background: #FAFCFF;
+          border-radius: 4px;
+          border: 1px solid #DAE2F2;
+        }
+      }
+
+
+    }
+  }
+}

+ 183 - 0
src/pages/costLibraryManagement/basicCostManagement/personnelClassificationMana/tableSelector.tsx

@@ -0,0 +1,183 @@
+import React, { Key, useEffect, useState } from "react";
+import { Input, Select } from 'antd'
+import { KCIMTable } from "@/components/KCIMTable";
+import { createFromIconfontCN } from "@ant-design/icons";
+
+
+import { ModalForm, ProColumns, ProFormSelect, ProFormText } from "@ant-design/pro-components";
+
+import { set } from "lodash";
+import { getAddableTableData } from "./service";
+
+// import './style.less';
+
+
+interface TableSelecterProps {
+    record: any
+}
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+
+const TableSelecter = ({ record, open, title, onVisibleChange, rowKey = 'id', request, onFinish, defaultSelectedKeys }: {
+    record: any, open: boolean, title: string, onVisibleChange: (bool: boolean) => void, defaultSelectedKeys: Key[],
+    rowKey?: string, request?: (params: any) => Promise<any>, onFinish?: (selectedKeys: React.Key[], selectedRows: any[]) => void
+}) => {
+
+
+    const Table = React.forwardRef(({ }: TableSelecterProps, ref) => {
+
+        const [datasource, set_datasource] = useState<any[]>([]);
+        const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
+        const [selectedRows, set_selectedRows] = useState<any[]>([]);
+        const [showList, set_showList] = useState<any[]>([]);
+        const [filter, set_filter] = useState<undefined | any>(undefined);
+        const [code, set_code] = useState<undefined | any>(undefined);
+        const [keyword, set_keyword] = useState<string | undefined>(undefined);
+
+
+        const columns: ProColumns[] = [
+            {
+                title: '工号',
+                dataIndex: 'account',
+            },
+            {
+                title: '姓名',
+                dataIndex: 'name',
+            },
+        ];
+
+
+        const onSelectChange = (newSelectedRowKeys: React.Key[], selectedRows: any) => {
+            setSelectedKeys([...newSelectedRowKeys]);
+            set_selectedRows([...selectedRows]);
+
+        };
+
+        const saveHandle = async () => {
+            const selectedRowkeys = selectedRows.map((a) => a[`${rowKey}`]);
+            const rows = datasource.filter((a) => selectedRowkeys.includes(a[`${rowKey}`]));
+            onFinish && onFinish(selectedKeys, rows);
+        }
+
+        const getTableData = async () => {
+
+            const resp = await getAddableTableData(record.costTypeCode);
+
+            let selectedCodes: string[] = [];
+            let selectedRows: any[] = [];
+            if (resp) {
+                const data = resp.map((a: any) => {
+                    if (defaultSelectedKeys.includes(a[`${rowKey}`])) {
+                        selectedCodes.push(a[`${rowKey}`]);
+                        selectedRows.push(a);
+                        const needItem = record.departList.filter((b: any) => a[`${rowKey}`] == b[`${rowKey}`]);
+
+                        return {
+                            ...a,
+                            flag: needItem[0].isManager ? true : false
+                        }
+                    } else {
+                        return a
+                    }
+                });
+
+                set_showList(data);
+                set_selectedRows([...selectedRows]);
+                setSelectedKeys([...selectedCodes]);
+                set_datasource([...datasource, ...data]);
+            }
+
+
+            return Promise.resolve([]);
+        }
+
+        useEffect(() => {
+            // console.log({code, keyword});
+            const result = datasource.filter((a) => {
+                 return a.name?a.name.indexOf(keyword) != -1:false
+            });
+
+            set_showList([...result]);
+        }, [keyword])
+
+        useEffect(() => {
+            getTableData()
+        }, [])
+
+
+        return (
+            <div >
+                <div className="filter" style={{ display: 'flex', flexDirection: 'row', marginBottom: 8 }}>
+                    <ProFormText noStyle placeholder={'请输入'}
+                        fieldProps={{
+                            suffix: <IconFont style={{ color: '#99A6BF' }} type="iconsousuo" />,
+                            onChange: (e) => {
+                                if (e.target.value.length != 0) {
+                                    set_keyword(e.target.value);
+                                } else {
+                                    set_keyword('');
+                                }
+                            }
+                        }}
+                    />
+                </div>
+
+                <KCIMTable columns={columns}
+                    options={{
+                        density: true,
+                        setting: {
+                            listsHeight: 100,
+                        },
+                    }}
+                    rowKey={rowKey}
+                    scroll={{ y: 400 }}
+                    tableAlertRender={false}
+                    rowSelection={{
+                        // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
+                        // 注释该行则默认不显示下拉选项
+                        // selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+                        selectedRowKeys: selectedKeys,
+                        onChange: onSelectChange,
+                    }}
+                    pagination={{ showTitle: false, showSizeChanger: false,simple:true }}
+                    dataSource={showList}
+
+                />
+                <div className='footer'>
+                    <span className='cancel' onClick={() => close()}>取消</span>
+                    <span className='ok' onClick={() => saveHandle()}>{`确认(${selectedKeys.length > 0 && selectedKeys.length})`}</span>
+                </div>
+            </div>
+
+        )
+    });
+
+    const close = () => {
+        onVisibleChange && onVisibleChange(false);
+    }
+
+
+    return (
+        <ModalForm className="TableSelecter" title={title} width={400} submitter={{
+            render: false
+        }} open={open} modalProps={{
+            closable: false,
+        }}>
+            <Table
+                // ref={tableSelecterRef}
+                record={undefined}
+            ></Table>
+        </ModalForm>
+    )
+
+}
+
+
+
+
+export default TableSelecter

+ 467 - 0
src/pages/costLibraryManagement/reportMana/reportColumnMana/index.tsx

@@ -0,0 +1,467 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 17:35:39
+ * @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 { ActionType, ProFormInstance, ProFormRadio } from '@ant-design/pro-components';
+import { ModalForm, ProFormDependency, ProFormDigit, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Popconfirm, Modal, Switch,Form } from 'antd';
+import { Key, useEffect, useRef, useState } from 'react';
+
+import { addChildReportList, addData, delData, editData, getReportListTableData, getReportListType } from './service';
+
+import './style.less';
+
+import '../../../../utils/zhongtaiB';
+import React from 'react';
+import KCIMPagecontainer from '@/components/KCIMPageContainer';
+import { KCIMTable } from '@/components/KCIMTable';
+import TableTransfer from './transform';
+import { getTargetDic } from '@/services/auth';
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+let currentEditRow:any = undefined;
+
+const reportColumnMana = ()=> {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const tableRef = useRef<ActionType>();
+
+    //const [currentEditRow, set_currentEditRow] = useState<any | undefined>(undefined);
+
+    const [ifShowModal, set_ifShowModal] = useState(false);
+
+    const ref = React.createRef<{ save: any; getSelectedKeys: any }>();
+
+    const columns: ProColumns[] = [
+        {
+            title: '列代码',
+            dataIndex: 'code',
+        },
+        {
+            title: '列名称',
+            dataIndex: 'name',
+            ellipsis: true
+        },
+        {
+            title: '列标题',
+            dataIndex: 'headerText',
+            ellipsis: true
+        },
+        {
+            title: '列类型',
+            dataIndex: 'typeName',
+            ellipsis: true,
+            // render:(_:any)=>_ == 1?'指标':'自定义SQL'
+        },
+        {
+            title: '取数类型',
+            dataIndex: 'dataSource',
+            ellipsis: true,
+            //render: (_: any) => _ == 1 ? '指标' : '自定义SQL',
+            renderText(num, record, index, action) {
+                return num == 1 ? '计算公式' : '自定义SQL'
+            },
+        },
+        {
+            title: '取数来源',
+            width: 200,
+            ellipsis: true,
+            render: (_: any, record: any) => {
+
+                if (record.dataSource == 1) return record.formula;
+                if (record.dataSource == 2) return record.sql
+            }
+        },
+        {
+            title: '子列',
+            width: 200,
+            ellipsis: true,
+            dataIndex: 'childColumnList',
+            render: (_: any, record: any) => {
+                if (record.childColumnList) {
+                    return record.childColumnList.reduce((prev: any, cur: any) => {
+                        return `${prev.length > 0 ? prev + '|' : prev}${cur.headerText}`
+                    }, '')
+                }
+
+            }
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                
+                return [
+                    <a key='edit_child' onClick={() => {currentEditRow = record;  addReportColumnChild(record) }}>子列</a>,
+                    <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+
+    ]
+
+    const transferTableColumn: ProColumns[] = [
+        {
+            title: '列名称',
+            dataIndex: 'name',
+            ellipsis: true
+            // render:(_:any)=>_ == 1?'指标':'自定义SQL'
+        },
+        {
+            title: '列标题',
+            dataIndex: 'headerText',
+            ellipsis: true
+            // render:(_:any)=>_ == 1?'指标':'自定义SQL'
+        },
+    ]
+
+
+    const getTableData = async (params: any) => {
+        const resp = await getReportListTableData(params);
+        if (resp) {
+            return {
+                data: 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 updateTable = async (formVal: any, type: 'EDIT' | "ADD" | 'EDIT_CHILD') => {
+
+        let result = {
+            name: formVal.name,
+            headerText: formVal.headerText,
+            type:formVal.type,
+            dataType: formVal.dataType,
+            dataSource: formVal.dataSource,
+            formula:formVal.dataSource == 1 ? formVal.formula:'',
+            sql:formVal.dataSource == 2?formVal.sql:'',
+            decimalPlace:formVal.dataType == 3 ?formVal.decimalPlace:undefined,
+            permil:formVal.dataType == 3?(formVal.permil?'1':'0'):undefined
+        }
+
+        if (type == 'ADD') {
+            const resp = await addData({ ...result });
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+        }
+        if (type == 'EDIT') {
+            const resp = await editData({ ...result,id:formVal.id });
+            if (resp) {
+                    tableRef.current?.reload();
+                    message.success('操作成功!');
+            }
+        }
+        return true;
+
+    }
+
+    const formRef = useRef<ProFormInstance>();
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' | 'EDIT_CHILD' }) => {
+
+        return (
+            <ModalForm
+                title={`${type == 'EDIT' ? '编辑' : '新增'}报表列`}
+                width={352}
+                formRef={formRef}
+                initialValues={type == 'EDIT' ? { ...record,permil:record.permil == '1'?true:false } : {decimalPlace:2}}
+                trigger={
+                    type == 'EDIT_CHILD' ? <a key="edit_child" >子列</a> : type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT' ? { ...record, ...val, sql: val.sql ? val.sql : '', } : { ...val }, type);
+                }}
+                colProps={{ span: 24 }}
+                modalProps={{
+                    destroyOnClose: true
+                }}
+                grid
+            >
+                {
+                    (type != 'EDIT_CHILD') && (
+                        <>
+                            <ProFormText
+                                name="name"
+                                label="列名称:"
+                                placeholder="请输入"
+                                rules={[{ required: true, message: '列名称不能为空!' }]}
+                            />
+                            <ProFormText
+                                name="headerText"
+                                label="列标题:"
+                                placeholder="请输入"
+                                rules={[{ required: true, message: '列标题不能为空!' }]}
+                            />
+                            <ProFormSelect
+                                name="type"
+                                label="列类型:"
+                                placeholder="请选择"
+                                request={async () => {
+                                    const resp = await getReportListType();
+                                    if (resp) {
+                                        return resp.map((a: any) => ({ label: a.name, value: a.code }));
+                                    }
+                                    return []
+                                }}
+                                rules={[{ required: true, message: '列类型不能为空!' }]}
+                            />
+
+
+                            <ProFormRadio.Group
+                                name="dataType"
+                                label="数据格式:"
+                                options={[
+                                    {
+                                        label: '文本',
+                                        value: 1,
+                                    },
+                                    {
+                                        label: '百分比',
+                                        value: 2,
+                                    },
+                                    {
+                                        label: '数值',
+                                        value: 3,
+                                    },
+                                ]}
+                                rules={[{ required: true, message: '取数格式不能为空!' }]}
+                            />
+                            <ProFormDependency name={['dataType']}>
+                                {
+                                    ({ dataType }) => dataType == 3 && (
+                                        <>
+                                            <ProFormDigit
+                                                name="decimalPlace"
+                                                label="小数位:"
+                                                colProps={{ span: 18 }}
+                                                placeholder="例:([1]+[2])/[3]"
+                                                rules={[{ required: true, message: '小数位不能为空!' }]}
+                                            />
+                                            <Form.Item name='permil'>
+                                                <Switch  size='small' style={{ marginTop: 26, marginLeft: 8 }} />
+                                            </Form.Item>
+                                            
+                                            <span style={{ marginTop: 23, marginLeft: 4 }}>千分号</span>
+                                        </>
+
+                                    )
+                                }
+                            </ProFormDependency>
+
+
+                            <ProFormSelect
+                                name="dataSource"
+                                label="取数类型:"
+                                placeholder="请选择"
+                                options={[
+                                    { label: '计算公式', value: 1 },
+                                    { label: '自定义SQL', value: 2 }
+                                ]}
+                                rules={[{ required: true, message: '取数类型不能为空!' }]}
+                            />
+                            
+                            <ProFormDependency name={['dataSource']}>
+                                {
+                                    ({ dataSource }) => dataSource == 1 && (
+                                        <>
+                                             <ProFormSelect
+                                                label={<><span style={{color:'#ff4d4f',fontSize:17,fontWeight:300,paddingRight:5}}>*</span>计算公式:</>}
+                                                name='line'
+                                                placeholder="插入列"
+                                                request={async ()=>{
+                                                       const resp = await getReportListTableData({pageSize:500,current:1});
+                                                       if(resp){
+                                                            return resp.list.map((a)=>({label:a.name,value:a.code}))
+                                                       }
+                                                       return []
+                                                }}
+                                                fieldProps={{
+                                                      onChange(value, option) {
+                                                        const _formula = formRef.current?.getFieldValue('formula');
+                                                        formRef.current?.setFieldValue('formula',`${_formula?_formula:''}[${value}]`)
+                                                      },
+                                                }}
+                                                // rules={[{ required: , message: '计算公式不能为空!' }]}
+                                            />
+                                            <ProFormTextArea
+                                                name="formula"
+                                                // colProps={{ span: 16 }}
+                                                placeholder="例:([1]+[2])/[3]"
+                                                rules={[{ required: true, message: '计算公式不能为空!' }]}
+                                            />
+                                           
+                                        </>
+                                    )
+                                }
+                            </ProFormDependency>
+                            <ProFormDependency name={['dataSource']}>
+                                {
+                                    ({ dataSource }) => dataSource == 2 && (
+                                        <ProFormTextArea name={'sql'} label='取数来源:' rules={[{ required: true, message: '取数来源不能为空!' }]} />
+                                    )
+                                }
+                            </ProFormDependency>
+                        </>
+                    )
+                }
+
+            </ModalForm>
+        )
+    }
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+
+    }
+
+    const onSaveHandle = async (keys:Key[],rows:any[]) => {
+           const result = {
+            parentCode:currentEditRow.code,
+            childColumnList:rows
+           }
+           const resp = await addChildReportList(result);
+           if(resp){
+               currentEditRow = undefined
+               message.success('操作成功!');
+               tableRef.current?.reload();
+           }
+           
+    }
+
+    const addReportColumnChild = (record:any) => {
+
+        const ref = React.createRef<{ save: any; }>();
+    
+
+        Modal.confirm({
+            title: `选择报表列`,
+            icon: <></>,
+            width: 750,
+            centered: true,
+            okText: '确定',
+            cancelText: '取消',
+            content: <TableTransfer
+                ref={ref}
+                record={record}
+                onSave={onSaveHandle}
+                leftColumns={transferTableColumn}
+                rightColumns={transferTableColumn} dataSource={[]}
+            ></TableTransfer>,
+            onOk: () => {
+                return ref.current && ref.current.save();
+            }
+        })
+    }
+
+
+    useEffect(() => {
+
+    }, [])
+
+    return (
+        <KCIMPagecontainer className='reportColumnMana' title={false}>
+
+            <div className='toolBar'>
+                <div className='filter'>
+                <div className='filterItem' >
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 列类型:</span>
+                        <ProFormSelect noStyle placeholder={'请选择类型'}
+                            width={160}
+                            request={async () => {
+                                const resp = await getReportListType();
+                                if (resp) {
+                                    return resp.map((a: any) => ({ label: a.name, value: a.code }));
+                                }
+                                return []
+                            }}
+                            fieldProps={{
+                                onChange(value, option) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        columnType: value
+                                    });
+                                },
+                            }}
+                        />
+                    </div>
+                    <div className='filterItem' style={{ marginLeft: 16 }}>
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 列标题:</span>
+                        <Input placeholder={'请输入'} allowClear width={160}
+                            suffix={
+                                <IconFont type="iconsousuo" onClick={() => tableDataSearchHandle('columnName')} />
+                            }
+                            onChange={(e) => {
+                                set_tableDataSearchKeywords(e.target.value);
+                                if (e.target.value.length == 0) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        columnName: ''
+                                    });
+                                }
+                            }}
+                            onPressEnter={(e) => {
+
+                                set_tableDataFilterParams({
+                                    ...tableDataFilterParams,
+                                    columnName: (e.target as HTMLInputElement).value
+                                });
+                            }}
+
+                        />
+                    </div>
+                </div>
+                <div className='btnGroup'>
+                    <UpDataActBtn record type='ADD' />
+                </div>
+            </div>
+
+            <div style={{ marginTop: 16 }}>
+                <KCIMTable columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
+            </div>
+        </KCIMPagecontainer>
+    )
+}
+
+export default reportColumnMana

+ 153 - 0
src/pages/costLibraryManagement/reportMana/reportColumnMana/service.ts

@@ -0,0 +1,153 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-02 15:03:09
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export type ReportListTableDataType = {
+  id: number,
+  hospId: number,
+  code: number,
+  name: string,
+  headerText: string,
+  dataSource: number,
+  columnType: string,
+  columnTypeName: string,
+  sql: string,
+  indicatorCode: string,
+  indicatorCodeName: string,
+  childColumnList: any[],
+}
+
+
+export const getReportListTableData = (params?: any) => {
+  return request<{
+    current: number;
+    list: ReportListTableDataType[];
+    pageSize: number;
+    totalCount: number;
+    totalPage: number;
+  }>('/costAccount/report/getColumnList', {
+    method: 'GET',
+    params: { ...params }
+  });
+};
+
+
+//新增报表
+export type AddTableDataType = {
+  "name":string, //列名称
+  "headerText":string, //列标题
+  "type":string, //报表列类型 取字典类型
+  "dataType": number, //0 未知 1 文本 3 数值 2百分比
+  "dataSource": number, //数据来源 1 计算公式 2自定义SQL
+  "formula"?:string, //计算公式
+  "sql"?:string, //自定义SQL
+  "decimalPlace"?: number, //小数位
+  "permil"?: string //是否有千分号
+}
+
+export const addData = (data: AddTableDataType) => {
+  return request('/costAccount/report/addColumn', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+
+
+//编辑表格数据
+
+export type ManaIndicItemTableRowEditType = {
+  id: number;
+} & AddTableDataType
+
+export const editData = (data: any) => {
+  return request('/costAccount/report/editColumn', {
+    method: 'POST',
+    data
+  });
+};
+
+//删除表格操作
+export const delData = (id: string) => {
+  return request('/costAccount/report/deleteColumn', {
+    method: 'POST',
+    params: { id }
+  });
+};
+
+
+//添加报表列
+export const addReportTableList = (data: any) => {
+  return request('/performance/report/addReportColumn', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+//获取子列报表列
+
+export const getChildReportList = (columnCode: string) => {
+  return request('/costAccount/report/getChildColumnList', {
+    method: 'GET',
+    params: { columnCode }
+  });
+};
+
+//添加子列报表列
+
+export type AddChildReportListDataType = {
+  parentCode: string,
+  childColumnList: {
+    "id":number, //主键
+    "hospId": number, //医院id
+    "parentColumnCode": number, //主列代码
+    "code": number, //列代码
+    "name":string, //列名
+    "headerText": string, //列标题
+    "createUser": string, //创建人
+    "createTime": string, //创建时间
+    "updateUser": string, //更新人
+    "updateTime": string, //更新时间
+    "deleteUser":string, //删除人
+    "deleteTime": string, //删除时间
+    "delFlag": number //删除标志  0正常 1作废
+  }[]
+}
+
+export const addChildReportList = (data: AddChildReportListDataType) => {
+  return request('/costAccount/report/addChildColumn', {
+    method: 'POST',
+    data: { ...data }
+  });
+};
+
+//获取报表列类型
+export const getReportListType = () => {
+  return request('/costAccount/report/getColumnType', {
+    method: 'GET',
+  });
+};
+
+
+
+
+
+
+
+
+

+ 74 - 0
src/pages/costLibraryManagement/reportMana/reportColumnMana/style.less

@@ -0,0 +1,74 @@
+.TableSelecter {
+  .footer {
+       display: flex;
+       flex-direction:row;
+       justify-content: flex-end;
+       margin-bottom:-10px;
+       margin-top: 15px;
+       span {
+           display: inline-block;
+           width: 56px;
+           height: 24px;  
+           font-size: 14px;
+           line-height: 23px;
+           text-align: center;
+           border-radius: 4px;
+           cursor: pointer;
+
+           &.ok {
+               color: #FFFFFF;
+               background:#3377FF;
+               margin-left: 8px;
+           }
+           &.cancel {
+               border: 1px solid #DAE2F2;
+           }
+       }
+
+  }
+}
+
+
+.reportColumnMana {
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      .add {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 132 - 0
src/pages/costLibraryManagement/reportMana/reportColumnMana/transform.tsx

@@ -0,0 +1,132 @@
+import React, { Key, useEffect, useImperativeHandle, useState } from "react";
+import {Transfer} from 'antd'
+import { TransferItem, TransferProps } from 'antd/es/transfer';
+import { ColumnsType } from 'antd/es/table';
+import { difference } from "lodash";
+import { TableRowSelection } from 'antd/es/table/interface';
+import { KCIMTable } from "@/components/KCIMTable";
+import { ProColumns } from "@ant-design/pro-components";
+import { getChildReportList } from "./service";
+
+
+interface TableTransferProps extends TransferProps<TransferItem> {
+    leftColumns:ProColumns[];
+    rightColumns: ProColumns[];
+    record:any,
+    onSave:(selectedKeys:Key[],selectedRowKeys:any[])=>void;
+}
+
+const TableTransfer = React.forwardRef(({ leftColumns, rightColumns,record,onSave, ...restProps }: TableTransferProps, ref) => {
+
+    const [_data, _set_data] = useState<any>();
+    const [targetKeys, setTargetKeys] = useState<string[]>([]);
+    const [datasource, set_datasource] = useState<any[]>([]);
+    const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
+
+    //获取列表
+    const getFuncList = async () => {
+
+        const resp = await getChildReportList(record.code);
+        if (resp) {
+            _set_data(resp);
+            //const allData = resp.allEmployees.concat(resp.checkEmployees);
+            set_datasource(resp);
+            const defaultSelctedkeys = record.childColumnList?record.childColumnList.map((a:any)=>a.code):[]
+            setTargetKeys(defaultSelctedkeys);
+        }
+    }
+
+    const onChange = (nextTargetKeys: string[]) => {
+        setTargetKeys(nextTargetKeys);
+    };
+
+    const onSelectChange = (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => {
+        //console.log('sourceSelectedKeys:', sourceSelectedKeys,'targetSelectedKeys:',targetSelectedKeys);
+        setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
+    };
+
+    useImperativeHandle(ref, () => ({
+        save: async () => {
+            const items = datasource.filter(a => targetKeys.includes(a.code));
+            onSave(targetKeys,items);
+        }
+    }));
+
+    useEffect(() => {
+        getFuncList();
+    }, [])
+
+    return (
+        <Transfer className='TableTransfer' showSearch
+            titles={['待选项', '已选项']}
+            locale={{
+                itemUnit: '项',
+                itemsUnit: '项',
+                searchPlaceholder: '请输入',
+            }}
+            oneWay={false}
+            onChange={onChange}
+            onSelectChange={onSelectChange}
+            dataSource={datasource}
+            rowKey={record => record.code}
+            targetKeys={targetKeys}
+            selectedKeys={selectedKeys}
+            filterOption={(inputValue, item) => {
+                return item.name!.indexOf(inputValue) !== -1
+
+            }}
+        >
+            {({
+                direction,
+                filteredItems,
+                onItemSelectAll,
+                onItemSelect,
+                selectedKeys: listSelectedKeys,
+                disabled: listDisabled,
+            }) => {
+
+                // console.log({ filteredItems, listSelectedKeys,direction });
+                const columns = direction === 'left' ? leftColumns : rightColumns;
+
+                const rowSelection: TableRowSelection<TransferItem> = {
+                    getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
+                    onSelectAll(selected, selectedRows) {
+                        const treeSelectedKeys = selectedRows.map(({ code }) => code);
+                        const diffKeys = selected
+                            ? difference(treeSelectedKeys, listSelectedKeys)
+                            : difference(listSelectedKeys, treeSelectedKeys);
+                        onItemSelectAll(diffKeys as string[], selected);
+                    },
+                    onSelect({ code }, selected) {
+                        onItemSelect(code as string, selected);
+                    },
+                    selectedRowKeys: listSelectedKeys,
+                };
+
+                return (
+                    <KCIMTable
+                        rowSelection={rowSelection}
+                        columns={columns as TransferItem[]}
+                        dataSource={filteredItems}
+                        size="small"
+                        bordered={false}
+                        rowKey={'code'}
+                        pagination={{ showTitle: false, pageSize: 9, showLessItems: false, simple: true, showTotal: () => false }}
+                        tableAlertRender={false}
+                        style={{ pointerEvents: listDisabled ? 'none' : undefined }}
+                        onRow={({ code, disabled: itemDisabled }) => ({
+                            onClick: () => {
+                                if (itemDisabled || listDisabled) return;
+                                onItemSelect(code as string, !listSelectedKeys.includes(code as string));
+                            },
+                        })}
+                    />
+                );
+            }}
+        </Transfer>
+    )
+});
+
+export default TableTransfer
+
+

+ 565 - 0
src/pages/costLibraryManagement/reportMana/reportListMana/index.tsx

@@ -0,0 +1,565 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 15:39:51
+ * @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 { ActionType, arrayMoveImmutable, useRefFunction } from '@ant-design/pro-components';
+import { ModalForm, ProFormSelect, ProFormText } from '@ant-design/pro-form';
+import { ProColumns } from '@ant-design/pro-table';
+import { Dropdown, Input, MenuProps, message, Modal, Switch, Tooltip, Popconfirm } from 'antd';
+import { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
+import Transfer, { TransferItem, TransferProps } from 'antd/es/transfer';
+import React, { Key } from 'react';
+import { useEffect, useRef, useState } from 'react';
+
+
+import { getReportColumn, getClolumnTableData, addReport, editReport, editReportTbaleData, delLeftReportData, batchDelTableData, addReportTbaleData, delData } from './service';
+
+
+import './style.less';
+
+
+import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
+
+import '../../../../utils/zhongtaiB'
+import KCIMPagecontainer from '@/components/KCIMPageContainer';
+import { KCIMTable } from '@/components/KCIMTable';
+import { getTargetDic } from '@/services/auth';
+import TableSelecter from './tableSelector';
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+var temp_dataSource: any[] = [];
+let _currentSelectedType: any = undefined;
+
+const reportListMana = () => {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const [selectedRowKeys, set_selectedRowKeys] = useState<Key[]>([]);
+    const [typeList, set_typeList] = useState<any[]>([]);
+    const [showTypeListArr, set_showTypeListArr] = useState<any[]>([]);
+    const [currentSelectedType, set_currentSelectedType] = useState<any | undefined>(undefined);
+
+
+    const [tableSelecterVisible,set_tableSelecterVisible] = useState(false);
+    const [dataSource, setDataSource] = useState<any[]>([]);
+    const SortableItem = SortableElement((props: any) => <tr {...props} />);
+    const SortContainer = SortableContainer((props: any) => <tbody {...props} />);
+
+    const [currentEditLeftData, set_currentEditLeftData] = useState<any | undefined>(undefined);
+
+    const [ifEditTable, set_ifEditTable] = useState(true);
+
+    const tableRef = useRef<ActionType>();
+
+    const DragHandle = SortableHandle(() => <img width={16} style={{ cursor: 'pointer' }} src={require('../../../../../static/tuozhuai_icon.png')} alt="" />);
+
+    const column: ProColumns[] = [
+
+        {
+            title: '列名称',
+            width: 120,
+            ellipsis: true,
+            dataIndex: 'columnName',
+
+        },
+        {
+            title: '列标题',
+            width: 160,
+            dataIndex: 'columnHeaderText',
+
+        },
+        {
+            title: '主键',
+            dataIndex: 'primaryKey',
+            render: (_: any, record: any) => {
+                return <Switch disabled={!ifEditTable} size='small' checked={_} onChange={(bool) => switchChangeHandle(bool, record, 'primaryKey')} />
+            }
+        },
+        {
+            title: '隐藏',
+            dataIndex: 'hide',
+            render: (_: any, record: any) => {
+                return <Switch disabled={!ifEditTable} size='small' checked={_} onChange={(bool) => switchChangeHandle(bool, record, 'hide')} />
+            }
+        },
+        {
+            title: '冻结',
+            dataIndex: 'freeze',
+            render: (_: any, record: any) => {
+                return <Switch disabled={!ifEditTable} size='small' checked={_ == '1'} onChange={(bool) => switchChangeHandle(bool, record, 'freeze')} />
+            }
+        },
+        {
+            title: '排序',
+            dataIndex: 'sortStatus',
+            render: (_: any, record: any) => {
+                return <Switch disabled={!ifEditTable} size='small' checked={_ == '1'} onChange={(bool) => switchChangeHandle(bool, record, 'sortStatus')} />
+            }
+        },
+        {
+            title: '操作',
+            key: 'option',
+            valueType: 'option',
+            render: (_: any, record: any) => {
+
+                return [
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record.id)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+    ]
+
+    const [tableColumn, set_tableColumn] = useState<ProColumns[] | any[]>(column);
+
+
+
+
+    const getTableData = async (params: any) => {
+        const { reportCode } = params;
+
+        if (reportCode) {
+            const resp = await getClolumnTableData({...params,pageSize:500,current:1});
+            if (resp) {
+                //const dataSorted = resp.sort((prev:any,cur:any)=>prev.sort - cur.sort);
+                setDataSource(resp.list);
+                temp_dataSource = [...resp.list];
+
+            }
+
+        }
+
+    }
+
+    const switchChangeHandle = (checked: boolean, record: any, key: string) => {
+
+        const newData = temp_dataSource.map((a: any) => {
+            if (a.id == record.id) {
+                return { ...a, [`${key}`]: checked ? 1 : 0 }
+            }
+            return a
+        });
+
+        setDataSource([...newData]);
+        updateTable(undefined, 'EDIT', newData)
+    }
+
+    //获取左侧单元
+    const getPageLeftReports = async () => {
+        const resp = await getReportColumn();
+
+        if (resp) {
+
+            set_typeList(resp);
+            set_showTypeListArr(resp);
+        }
+    }
+
+    const delTableData = async (id:number) => {
+        const resp = await delData(id);
+        if(resp){
+              message.success('操作成功!');
+              getTableData({ reportCode: _currentSelectedType.code });
+        }
+    }
+
+    const batchDelHandle = async () => {
+        const resp = await batchDelTableData(selectedRowKeys);
+        if (resp) {
+            message.success('操作成功!');
+            set_selectedRowKeys([]);
+            getTableData({ reportCode: _currentSelectedType.code });
+        }
+    }
+
+    const tableSelecterCommit = async (keys:Key[], rows:any[]) => {
+          const result = rows.map((a,index)=>({
+            reportCode:_currentSelectedType.code,
+            columnCode:a.code,
+            columnHeaderText:a.headerText,
+            columnName:a.name,
+            sort:index+1
+          }))
+          const resp = await addReportTbaleData(result);
+          if(resp){
+            message.success('操作成功');
+            set_tableSelecterVisible(false);
+            getTableData({ reportCode: _currentSelectedType.code });
+          }
+    }
+
+
+    const updateTable = async (formVal: any, type: 'EDIT' | "ADD" | 'ADD_LEFTDATA' | 'EDIT_LEFTDATA', data?: any[]) => {
+
+        // console.log({formVal,type});
+
+        if (type == 'ADD_LEFTDATA') {
+            const resp = await addReport({
+                name: formVal.name,
+                shortName: formVal.shortName,
+                type: formVal.type
+            });
+            if (resp) {
+                getPageLeftReports();
+            }
+        }
+
+
+
+        if (type == 'EDIT_LEFTDATA') {
+            const resp = await editReport({
+                id: formVal.id,
+                name: formVal.name,
+                shortName: formVal.shortName,
+                type: formVal.type
+            });
+            if (resp) {
+                getPageLeftReports();
+            }
+        }
+
+        if (type == 'EDIT') {
+
+            let newDataSource = data?.map((a: any, index: number) => {
+                //更新排序
+                return { ...a, sort: index + 1 }
+            })
+            const resp = await editReportTbaleData(newDataSource);
+            if (resp) {
+                getTableData({ reportCode: _currentSelectedType.code });
+            }
+        }
+
+        return true;
+
+    }
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' | 'ADD_LEFTDATA' | 'EDIT_LEFTDATA' }) => {
+
+        const getTrriger = () => {
+            if (type == 'ADD') {
+                return <span className='add'>新增</span>
+            }
+            if (type == 'EDIT') {
+                return <a key="edit" >编辑</a>
+            }
+            if (type == 'ADD_LEFTDATA') {
+                return (
+                    <div className='add'>
+                        <img src={require('../../../../../static/addIcon_black.png')} alt="" />
+                    </div>
+                )
+            }
+            if (type == 'EDIT_LEFTDATA') {
+                return <a key="edit" >编辑</a>
+            }
+        }
+
+        return (
+            <ModalForm
+                title={type == 'ADD_LEFTDATA' ? `新增报表` : `编辑报表`}
+                width={352}
+                initialValues={type == 'EDIT_LEFTDATA' ? { ...record } : {}}
+                trigger={
+                    getTrriger()
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT_LEFTDATA' ? { ...record, ...val } : val, type);
+                }}
+            >
+
+                <ProFormText
+                    label='报表名称:'
+                    name='name'
+                    rules={[{ required: true, message: '报表名称不能为空!' }]}
+                />
+                <ProFormText
+                    label='报表简称:'
+                    name='shortName'
+                    rules={[{ required: true, message: '报表简称不能为空!' }]}
+                />
+                <ProFormSelect
+                    name="type"
+                    label="报表类型:"
+                    placeholder="请选择"
+                    request={async () => {
+                        const resp = await getTargetDic('REPORT_TYPE');
+                        if (resp) {
+                            const { dataVoList } = resp;
+                            return dataVoList.map((a: any) => ({ label: a.name, value: a.code }));
+                        }
+                        return []
+                    }}
+                    rules={[{ required: true, message: '列类型不能为空!' }]}
+                />
+            </ModalForm>
+        )
+    }
+
+
+
+    interface DataType {
+        key: string;
+        title: string;
+        description: string;
+        disabled: boolean;
+        tag: string;
+    }
+
+    interface TableTransferProps extends TransferProps<TransferItem> {
+        dataSource: DataType[];
+        leftColumns: ColumnsType<DataType>;
+        rightColumns: ColumnsType<DataType>;
+        record: any
+    }
+ 
+
+
+    const moreItems: MenuProps['items'] = [
+        {
+            key: '1',
+            label: <UpDataActBtn key={'act'} record={currentEditLeftData} type='EDIT_LEFTDATA' />,
+        },
+        {
+            key: '2',
+            label: (
+                <a onClick={async (e) => {
+                    e.preventDefault();
+                    const resp = await delLeftReportData(currentEditLeftData.id);
+                    if (resp) {
+                        getPageLeftReports();
+                    }
+                }}>
+                    删除
+                </a>
+            ),
+        },
+        {
+            key: '3',
+            label: (<a onClick={async (e) => {
+                e.preventDefault();
+                // 选取要复制的文本
+                const textToCopy = currentEditLeftData.code;
+
+                // 创建一个临时的textarea元素
+                const tempTextArea = document.createElement("textarea");
+                tempTextArea.value = textToCopy;
+                document.body.appendChild(tempTextArea);
+
+                // 选中并复制文本
+                tempTextArea.select();
+                document.execCommand("copy");
+
+                // 移除临时元素
+                document.body.removeChild(tempTextArea);
+                message.success('复制成功!');
+
+            }}>
+                复制报表code
+            </a>),
+        },
+    ];
+
+
+
+    const onSortEnd = useRefFunction(
+        ({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {
+            if (oldIndex !== newIndex) {
+                const newData = arrayMoveImmutable({
+                    array: [...dataSource],
+                    fromIndex: oldIndex,
+                    toIndex: newIndex,
+                }).filter((el) => !!el);
+
+                const updatedSortArr = newData.map((item: any, index: number) => ({ ...item, sort: index }))
+                // setDataSource([...updatedSortArr]);
+                updateTable(undefined, 'EDIT', updatedSortArr)
+            }
+        },
+    );
+
+    const DraggableContainer = (props: any) => (
+        <SortContainer
+            useDragHandle
+            disableAutoscroll
+            helperClass="row-dragging"
+            onSortEnd={onSortEnd}
+            {...props}
+        />
+    );
+
+    const DraggableBodyRow = (props: any) => {
+        const { className, style, ...restProps } = props;
+
+        // function findIndex base on Table rowKey props and should always be a right array index
+        const index = dataSource.findIndex((x) => x.id === restProps['data-row-key']);
+
+        return <SortableItem index={index} {...restProps} />;
+    };
+
+
+
+
+
+    useEffect(() => {
+
+        if (currentSelectedType) {
+            set_tableDataFilterParams({ ...tableDataFilterParams, reportCode: currentSelectedType.code });
+            getTableData({ reportCode: currentSelectedType.code });
+        }
+    }, [currentSelectedType])
+
+    useEffect(() => {
+        if (showTypeListArr.length > 0) {
+            set_currentSelectedType(showTypeListArr[0]);
+            _currentSelectedType = showTypeListArr[0];
+            set_tableDataFilterParams({ ...tableDataFilterParams, reportCode: showTypeListArr[0].code });
+        }
+    }, [showTypeListArr]);
+
+    useEffect(() => {
+        if (ifEditTable) {
+            set_tableColumn([{
+                title: '排序',
+                dataIndex: 'sort',
+                width: 60,
+                className: 'drag-visible',
+                render: () => <DragHandle />
+            }, ...column,
+            ])
+        } else {
+            set_tableColumn(column);
+        }
+    }, [ifEditTable]);
+
+    useEffect(() => {
+        temp_dataSource = [...dataSource];
+    }, [dataSource])
+
+    useEffect(() => {
+        getPageLeftReports();
+    }, [])
+
+
+
+    return (
+        <KCIMPagecontainer title={false} className='reportListMana'>
+            <TableSelecter
+                onVisibleChange={(bool) => set_tableSelecterVisible(bool)}
+                title='添加'
+                rowKey={'code'}
+                defaultSelectedKeys={[]}
+                record={_currentSelectedType}
+                open={tableSelecterVisible}
+                onFinish={(keys, rows) => tableSelecterCommit(keys, rows)}
+            />
+            {selectedRowKeys.length > 0 && (
+                <div className='bottomBar'>
+                    <span>已选择<a>{selectedRowKeys.length}</a>项</span>
+                    <a onClick={() => batchDelHandle()}>批量删除</a>
+                </div>
+            )}
+            <div className='left'>
+                <div className='toolbar'>
+                    <Input placeholder={'报表名称'} allowClear
+                        suffix={
+                            <IconFont type="iconsousuo" />
+                        }
+                        style={{ width: 156 }}
+                        onChange={(e) => {
+                            const result = typeList.filter(item => item.reportName.indexOf(e.target.value) != -1);
+                            set_showTypeListArr(result);
+                        }}
+
+                    />
+                    <UpDataActBtn key={'act'} record={undefined} type='ADD_LEFTDATA' />
+
+                </div>
+
+                <div className='wrap'>
+                    {
+                        showTypeListArr.map((item, index) => {
+                            return (
+                                <div className={currentSelectedType ? currentSelectedType.id == item.id ? 'type on' : 'type' : 'type'}
+                                    key={index}
+                                    onClick={() => {
+                                        set_currentSelectedType(item)
+                                        _currentSelectedType = item;
+                                    }}
+                                >
+                                    <img className='icon' src={require('../../../../../static/reportIcon.png')} alt="" />
+                                    <div className='content'>
+                                        <Tooltip title={item.name} >
+                                            <div className='name'>{item.name}</div>
+                                            <div className='sub'>{item.typeName}</div>
+                                        </Tooltip>
+                                    </div>
+
+                                    <Dropdown menu={{ items: moreItems }} placement="bottom" onOpenChange={(bool) => { bool && set_currentEditLeftData(item) }}>
+                                        <div className='more'>
+                                            <img src={require('../../../../../static/more_point_gray.png')} alt="" />
+                                        </div>
+                                    </Dropdown>
+                                </div>
+                            )
+                        })
+                    }
+                </div>
+            </div>
+            <div className='right'>
+                <div className='toolBar'>
+                    <div className='filter'>
+                    </div>
+                    <div className='btnGroup'>
+                        {!ifEditTable && <span className='manaBtn' onClick={() => set_ifEditTable(true)}>管理列</span>}
+                        {
+                            ifEditTable && (
+                                <div className='inner'>
+                                    {/* <span className='save' onClick={() => updateTable(undefined, 'EDIT')}>保存</span> */}
+                                    <span className='add' onClick={() => set_tableSelecterVisible(true)}>添加</span>
+                                </div>
+                            )
+                        }
+                    </div>
+                </div>
+                <div style={{ marginTop: 16 }}>
+                    {currentSelectedType && <KCIMTable actionRef={tableRef} columns={tableColumn}
+                        scroll={{ y: 500 }}
+                        rowKey='id'
+                        dataSource={dataSource}
+                        tableAlertRender={false}
+                        rowSelection={{
+
+                            onChange(selectedRowKeys, selectedRows, info) {
+                                set_selectedRowKeys(selectedRowKeys);
+                            },
+                        }}
+                        components={{
+                            body: {
+                                wrapper: DraggableContainer,
+                                row: DraggableBodyRow,
+                            },
+                        }}
+                    />}
+                </div>
+            </div>
+        </KCIMPagecontainer>
+    )
+}
+
+
+export default reportListMana;

+ 117 - 0
src/pages/costLibraryManagement/reportMana/reportListMana/service.ts

@@ -0,0 +1,117 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-07 11:12:10
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-02 17:58:13
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { Key } from 'react';
+import { request } from 'umi';
+
+
+//获取左侧报表数据
+
+export const getReportColumn = () => {
+  return request('/costAccount/report/getReport', {
+    method: 'GET',
+  });
+};
+
+//获取表格数据
+
+export type  ClolumnTableDataType = {
+  id:number;
+  
+}
+
+export const getClolumnTableData = (params:{reportCode:string}) => {
+    return request('/costAccount/report/getReportColumn', {
+      method: 'GET',
+      params:{...params}
+    });
+};
+
+//获取可添加列表
+export const getAddableTableData = (reportCode:string) => {
+  return request('/costAccount/report/getReportCostColumn', {
+    method: 'GET',
+    params:{reportCode}
+  });
+};
+
+
+//新增报表
+
+
+export const addReport = (data:any) => {
+  return request('/costAccount/report/addReport', {
+    method: 'POST',
+    data
+  });
+};
+
+
+//编辑报表
+export const editReport = (data:any) => {
+  return request('/costAccount/report/editReport', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+
+//新增表格数据
+
+export const addReportTbaleData = (data:any) => {
+  return request('/costAccount/report/addReportColumn', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+//编辑表格数据
+
+export const editReportTbaleData = (data:any) => {
+    return request('/costAccount/report/editReportColumn', {
+      method: 'POST',
+      data
+    });
+};
+
+
+//删除表格操作
+export const delData = (id:number) => {
+    return request('/costAccount/report/deleteReportColumn', {
+      method: 'POST',
+      params:{id}
+    });
+};
+
+//删除左侧报表
+export const delLeftReportData = (id:number) => {
+  return request('/costAccount/report/deleteReport', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+//批量删除表格数据
+export const batchDelTableData = (ids:Key[]) => {
+  return request('/costAccount/report/batchDeleteReportColumn', {
+    method: 'POST',
+    data:[...ids]
+  });
+};
+
+
+
+

+ 254 - 0
src/pages/costLibraryManagement/reportMana/reportListMana/style.less

@@ -0,0 +1,254 @@
+.row-dragging {
+
+  .cost-ant-table-cell {
+    width: 130px;
+  }
+}
+
+.TableSelecter {
+
+  .pfm-ant-modal-footer {
+    display: none !important;
+  }
+  
+  .footer {
+       display: flex;
+       flex-direction:row;
+       justify-content: flex-end;
+       margin-top: 15px;
+       span {
+           display: inline-block;
+           width: 56px;
+           height: 24px;  
+           font-size: 14px;
+           line-height: 23px;
+           text-align: center;
+           border-radius: 4px;
+           cursor: pointer;
+
+           &.ok {
+               color: #FFFFFF;
+               background:#3377FF;
+               margin-left: 8px;
+           }
+           &.cancel {
+               border: 1px solid #DAE2F2;
+           }
+       }
+
+  }
+}
+
+.reportListMana {
+  width: 100%;
+  height: calc(100vh - 48px);
+  position: relative;
+
+  .bottomBar {
+    position: absolute;
+    bottom: -16px;
+    left: -16px;
+    width:102.5%;
+    height: 48px;
+    display: flex;
+    padding: 0 16px;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    background: #FFFFFF;
+box-shadow: 0px -8px 16px 0px rgba(64,85,128,0.1);
+
+    &>span {
+      font-size: 14px;
+      font-weight: 400;
+      color: #17181A;
+    }
+
+    &>a {
+      width: 80px;
+      height: 24px;
+      line-height: 24px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #FFFFFF;
+      text-align: center;
+      background: #3377FF;
+      border-radius: 4px;
+    }
+  }
+
+  .left {
+    float: left;
+    border-radius: 4px;
+    width: 220px;
+    height: calc(100vh - 80px);
+    overflow: scroll;
+    margin-right: 16px;
+    padding: 16px 8px;
+    background: #FFFFFF;
+
+    .toolbar {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      align-items: center;
+      padding: 0 8px;
+
+      .add {
+        cursor: pointer;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 24px;
+        height: 24px;
+        background: #FAFCFF;
+        border-radius: 4px;
+        border: 1px solid #DAE2F2;
+
+        &>img {
+          width: 16px;
+          height: 16px;
+        }
+      }
+    }
+
+    .wrap {
+      margin-top: 16px;
+
+      .type {
+        cursor: pointer;
+        height: 56px;
+        border-radius: 4px;
+        background: #FFFFFF;
+        display: flex;
+        padding-left: 8px;
+        padding-right: 8px;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 4px;
+
+        .icon {
+          width: 25px;
+          height: 25px;
+        }
+
+        .content {
+          width: 80%;
+          padding-left: 7px;
+
+          .name {
+            height: 15px;
+            font-size: 14px;
+            font-family: SourceHanSansCN-Medium, SourceHanSansCN;
+            font-weight: 500;
+            color: #17181A;
+            line-height: 15px;
+            margin-bottom: 8px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+
+          .sub {
+            height: 13px;
+            font-size: 12px;
+            font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+            font-weight: 400;
+            color: #7A8599;
+            line-height: 13px;
+          }
+        }
+
+        .more {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          width: 16px;
+          height: 16px;
+          border-radius: 4px;
+          background: #FFFFFF;
+
+          &>img {
+            width: 100%;
+            height: 100%;
+          }
+        }
+
+        &.on {
+          font-weight: 500;
+          color: #17181A;
+          background: #F0F2F5;
+        }
+
+        &:last-child {
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
+
+  .right {
+    float: left;
+    width: calc(100% - 236px);
+    padding: 16px;
+    border-radius: 4px;
+    background: #FFFFFF;
+
+    .toolBar {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      align-items: center;
+
+      .filter {
+        display: flex;
+        flex-direction: row;
+        justify-content: flex-start;
+        align-items: center;
+
+        .filterItem {
+          display: flex;
+          flex-direction: row;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+
+      .btnGroup {
+        .manaBtn {
+          cursor: pointer;
+          display: inline-block;
+          font-size: 14px;
+          font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+          font-weight: 400;
+          color: #FFFFFF;
+          line-height: 24px;
+          padding: 0 14px;
+          background: #3377FF;
+          border-radius: 4px;
+        }
+
+        .inner {
+          &>span {
+            cursor: pointer;
+            display: inline-block;
+            font-size: 14px;
+            font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+            font-weight: 400;
+            color: #FFFFFF;
+            line-height: 24px;
+            padding: 0 14px;
+            background: #3377FF;
+            border-radius: 4px;
+            margin-left: 8px;
+          }
+
+        }
+      }
+
+
+    }
+  }
+}

+ 203 - 0
src/pages/costLibraryManagement/reportMana/reportListMana/tableSelector.tsx

@@ -0,0 +1,203 @@
+import React, { Key, useEffect, useState } from "react";
+import { Input, Select } from 'antd'
+import { KCIMTable } from "@/components/KCIMTable";
+import { createFromIconfontCN } from "@ant-design/icons";
+
+
+import { ModalForm, ProColumns, ProFormSelect, ProFormText } from "@ant-design/pro-components";
+
+import { set } from "lodash";
+import { getAddableTableData } from "./service";
+import { getReportListType } from "../reportColumnMana/service";
+
+// import './style.less';
+
+
+interface TableSelecterProps {
+    record: any
+}
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+
+const TableSelecter = ({ record, open, title, onVisibleChange, rowKey = 'id', request, onFinish, defaultSelectedKeys }: {
+    record: any, open: boolean, title: string, onVisibleChange: (bool: boolean) => void, defaultSelectedKeys: Key[],
+    rowKey?: string, request?: (params: any) => Promise<any>, onFinish?: (selectedKeys: React.Key[], selectedRows: any[]) => void
+}) => {
+
+
+    const Table = React.forwardRef(({ }: TableSelecterProps, ref) => {
+
+        const [datasource, set_datasource] = useState<any[]>([]);
+        const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
+        const [selectedRows, set_selectedRows] = useState<any[]>([]);
+        const [showList, set_showList] = useState<any[]>([]);
+        const [filter, set_filter] = useState<undefined | any>(undefined);
+        const [code, set_code] = useState<undefined | any>(undefined);
+        const [keyword, set_keyword] = useState<string | undefined>(undefined);
+
+
+        const columns: ProColumns[] = [
+            {
+                title: '列名称',
+                dataIndex: 'name',
+            },
+            {
+                title: '列标题',
+                dataIndex: 'headerText',
+            },
+            {
+                title: '列类型',
+                dataIndex: 'typeName',
+            }
+        ];
+
+
+        const onSelectChange = (newSelectedRowKeys: React.Key[], selectedRows: any) => {
+            setSelectedKeys([...newSelectedRowKeys]);
+            set_selectedRows([...selectedRows]);
+
+        };
+
+        const saveHandle = async () => {
+            const selectedRowCodes = selectedRows.map((a) => a.code);
+            const rows = datasource.filter((a) => selectedRowCodes.includes(a.code));
+            onFinish && onFinish(selectedKeys, rows);
+        }
+
+        const getTableData = async () => {
+
+            const resp = await getAddableTableData(record.code);
+
+            let selectedCodes: string[] = [];
+            let selectedRows: any[] = [];
+            if (resp) {
+                const data = resp.map((a: any) => {
+                    if (defaultSelectedKeys.includes(a.code)) {
+                        selectedCodes.push(a.code);
+                        selectedRows.push(a);
+                        const needItem = record.departList.filter((b: any) => a.code == b.code);
+
+                        return {
+                            ...a,
+                            flag: needItem[0].isManager ? true : false
+                        }
+                    } else {
+                        return a
+                    }
+                });
+
+                set_showList(data);
+                set_selectedRows([...selectedRows]);
+                setSelectedKeys([...selectedCodes]);
+                set_datasource([...datasource, ...data]);
+            }
+
+
+            return Promise.resolve([]);
+        }
+
+        useEffect(() => {
+            // console.log({code, keyword});
+            const result = datasource.filter((a) => {
+                if (code == '' && keyword == '') return true;
+                return (code ? a.type == code : true) && (keyword ? a.headerText.indexOf(keyword) != -1 : true)
+            });
+
+            set_showList([...result]);
+        }, [code, keyword])
+
+        useEffect(() => {
+            getTableData()
+        }, [])
+
+
+        return (
+            <div >
+                <div className="filter" style={{ display: 'flex', flexDirection: 'row', marginBottom: 8 }}>
+                    <ProFormSelect noStyle placeholder={'列类型'} style={{ marginRight: 8, width: 180 }}
+                        request={async () => {
+                            const resp = await getReportListType();
+                            if (resp) {
+                                return resp.map((a: any) => ({ label: a.name, value: a.code }));
+                            }
+                            return []
+                        }}
+                        fieldProps={{
+                            onChange(value, option) {
+                                set_code(value ? value : '');
+                            },
+                        }}
+                    />
+                    <ProFormText noStyle placeholder={'列标题'}
+                        fieldProps={{
+                            suffix: <IconFont style={{ color: '#99A6BF' }} type="iconsousuo" />,
+                            onChange: (e) => {
+                                if (e.target.value.length != 0) {
+                                    set_keyword(e.target.value);
+                                } else {
+                                    set_keyword('');
+                                }
+                            }
+                        }}
+                    />
+                </div>
+
+                <KCIMTable columns={columns}
+                    options={{
+                        density: true,
+                        setting: {
+                            listsHeight: 100,
+                        },
+                    }}
+                    rowKey={rowKey}
+                    scroll={{ y: 400 }}
+                    tableAlertRender={false}
+                    rowSelection={{
+                        // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
+                        // 注释该行则默认不显示下拉选项
+                        // selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+                        selectedRowKeys: selectedKeys,
+                        onChange: onSelectChange,
+                    }}
+                    pagination={{ showTitle: false, showSizeChanger: true }}
+                    dataSource={showList}
+
+                />
+                <div className='footer'>
+                    <span className='cancel' onClick={() => close()}>取消</span>
+                    <span className='ok' onClick={() => saveHandle()}>{`确认(${selectedKeys.length > 0 && selectedKeys.length})`}</span>
+                </div>
+            </div>
+
+        )
+    });
+
+    const close = () => {
+        onVisibleChange && onVisibleChange(false);
+    }
+
+
+    return (
+        <ModalForm className="TableSelecter" title={title} width={400} submitter={{
+            render: false
+        }} open={open} modalProps={{
+            closable: false,
+        }}>
+            <Table
+                // ref={tableSelecterRef}
+                record={undefined}
+            ></Table>
+        </ModalForm>
+    )
+
+}
+
+
+
+
+export default TableSelecter

+ 359 - 0
src/pages/costLibraryManagement/reportMana/reportNavSet/index.tsx

@@ -0,0 +1,359 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 09:45:45
+ * @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, ProFormInstance } from '@ant-design/pro-components';
+import { ModalForm, ProFormDependency, ProFormSelect } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Popconfirm } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+import { getClolumnTableData, getReportColumn } from '../reportListMana/service';
+
+
+import { addData, delData, editData, getReportListTableData } from './service';
+
+import './style.less';
+
+
+const IconFont = createFromIconfontCN({
+    scriptUrl: '',
+});
+
+
+
+export default function ReportNavSet() {
+
+    const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+    const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+    const tableRef = useRef<ActionType>();
+    const formRef = useRef<ProFormInstance>();
+
+    const columns: ProColumns[] = [
+
+        {
+            title: '源报表名称',
+            dataIndex: 'reportName',
+        },
+        {
+            title: '报表列名称',
+            dataIndex: 'reportColumnName',
+        },
+        {
+            title: '目标报表名称',
+            dataIndex: 'redirectReportName',
+            // render:(_:any)=>_ == 1?'指标':'自定义SQL'
+        },
+        {
+            title: '跳转参数',
+            width: 400,
+            ellipsis: true,
+            dataIndex: 'redirectParameterDisplay',
+            render: (_: any, record: any) => {
+                if (record.redirectParameterDisplay) {
+                    const a = JSON.parse(record.redirectParameterDisplay);
+                    if (a) {
+                        return (a.map((item: any) => item.label)).join('|');
+                    } else {
+                        return ''
+                    }
+                }
+            }
+        },
+        {
+            title: '操作',
+            key: 'option',
+            width: 120,
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                return [
+                    <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+                    <Popconfirm
+                        title="是否确认删除?"
+                        key="del"
+                        onConfirm={() => delTableData(record)}
+                    >
+                        <a>删除</a>
+                    </Popconfirm>
+                ]
+            },
+        },
+
+    ]
+
+
+    const getTableData = async (params: any) => {
+        const resp = await getReportListTableData(params);
+        if (resp) {
+            return {
+                data: 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 updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
+
+        if (type == 'ADD') {
+            const resp = await addData({
+                redirectReportCode: formVal.targetReport.value,
+                redirectReportName: formVal.targetReport.label,
+                reportColumnCode: formVal.reportColumn.value,
+                reportColumnName: formVal.reportColumn.label,
+                reportCode: formVal.report.value,
+                reportName: formVal.report.label,
+                redirectParameter: (formVal.redirectParameter.map((a: any) => a.value)).join('|'),
+                redirectParameterDisplay: JSON.stringify(formVal.redirectParameter)
+            });
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+
+        }
+        if (type == 'EDIT') {
+
+            const resp = await editData({
+                id: formVal.id,
+                redirectReportCode: formVal.targetReport.value,
+                redirectReportName: formVal.targetReport.label,
+                reportColumnCode: formVal.reportColumn.value,
+                reportColumnName: formVal.reportColumn.label,
+                reportCode: formVal.report.value,
+                reportName: formVal.report.label,
+                redirectParameter: (formVal.redirectParameter.map((a: any) => a.value)).join('|'),
+                redirectParameterDisplay: JSON.stringify(formVal.redirectParameter)
+            });
+            if (resp) {
+                tableRef.current?.reload();
+                message.success('操作成功!');
+            }
+        }
+        return true;
+
+    }
+
+
+    const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
+
+        const redirectParameter = JSON.parse(record.redirectParameterDisplay ? record.redirectParameterDisplay : '[]');
+
+        return (
+            <ModalForm
+                title={`${type == 'EDIT' ? '编辑' : '新增'}报表跳转`}
+                width={400}
+                formRef={formRef}
+                initialValues={type == 'EDIT' ? {
+                    ...record,
+                    report: { label: record.reportName, value: record.reportCode },
+                    reportColumn: { label: record.reportColumnName, value: record.reportColumnCode },
+                    targetReport: { label: record.redirectReportName, value: record.redirectReportCode },
+                    redirectParameter: redirectParameter
+                } : {}}
+                trigger={
+                    type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
+                }
+                onFinish={(val) => {
+                    return updateTable(type == 'EDIT' ? { ...record, ...val } : { ...val }, type);
+                }}
+                modalProps={{destroyOnClose:true}}
+                colProps={{ span: 24 }}
+                grid
+            >
+
+                <ProFormSelect
+                    name="report"
+                    label="源报表标题:"
+                    placeholder="请选择"
+                    request={async () => {
+                        const resp = await getReportColumn();
+
+                        if (resp) {
+                            return resp.map((a: any) => ({ label: a.name, value: a.code }))
+                        }
+                        return []
+
+                    }}
+                    fieldProps={{
+                        labelInValue: true,
+                        onChange(value, option) {
+                            formRef?.current?.setFieldsValue({
+                                reportColumn:null,
+                                redirectParameter:[]
+                            })
+                        },
+                    }}
+                    rules={[{ required: true, message: '源报表名称不能为空!' }]}
+                />
+
+                <ProFormDependency name={['report']}>
+                    {
+                        ({ report }) => {
+                            // console.log({report});
+                            return (
+                                <ProFormSelect
+                                    name="reportColumn"
+                                    label="报表列标题:"
+                                    disabled={!report}
+                                    placeholder="请选择"
+                                    params={report}
+                                    request={async () => {
+                                        if (report) {
+                                            const { value: reportCode } = report;
+                                            const resp = await getClolumnTableData({ reportCode });
+                                            if (resp) {
+                                                return resp.list.map((a: any) => ({ label: a.columnHeaderText, value: a.columnCode }))
+                                            }
+                                            return []
+                                        } else {
+                                            return []
+                                        }
+
+                                    }}
+                                    fieldProps={{
+                                        labelInValue: true
+                                    }}
+                                    rules={[{ required: true, message: '报表列名称不能为空!' }]}
+                                />
+
+                            )
+                        }
+                    }
+                </ProFormDependency>
+                <ProFormSelect
+                    name="targetReport"
+                    label="目标报表名称:"
+                    placeholder="请选择"
+                    request={async () => {
+                        const resp = await getReportColumn();
+
+                        if (resp) {
+                            return resp.map((a: any) => ({ label: a.name, value: a.code }))
+                        }
+                        return []
+                    }}
+                    fieldProps={{
+                        labelInValue: true
+                    }}
+                    rules={[{ required: true, message: '目标报表名称不能为空!' }]}
+                />
+
+                <ProFormDependency name={['report']}>
+                    {
+                        ({ report }) => {
+                            // console.log({report});
+                            return (
+                                <ProFormSelect
+                                    name="redirectParameter"
+                                    label="跳转参数:"
+                                    disabled={!report}
+                                    placeholder="请选择"
+                                    params={report}
+                                    request={async () => {
+                                        if (report) {
+                                            const { value: reportCode } = report;
+                                            const resp = await getClolumnTableData({ reportCode });
+                                            if (resp) {
+                                                return resp.list.map((a: any) => ({ label: a.columnHeaderText, value: a.columnName }))
+                                            }
+                                        } else {
+                                            return []
+                                        }
+                                        return []
+
+                                    }}
+                                    fieldProps={{
+                                        labelInValue: true,
+                                        mode: 'multiple',
+                                        maxTagCount: 'responsive'
+                                    }}
+                                    rules={[{ required: true, message: '跳转参数不能为空!' }]}
+                                />
+
+                            )
+                        }
+                    }
+                </ProFormDependency>
+
+            </ModalForm>
+        )
+    }
+
+    const tableDataSearchHandle = (paramName: string) => {
+
+        set_tableDataFilterParams({
+            ...tableDataFilterParams,
+            [`${paramName}`]: tableDataSearchKeywords
+        })
+
+    }
+
+
+    useEffect(() => {
+
+    }, [])
+
+    return (
+        <KCIMPagecontainer className='ReportNavSet' title={false}>
+            <div className='toolBar'>
+                <div className='filter'>
+                    <div className='filterItem'>
+                        <span className='label' style={{ whiteSpace: 'nowrap' }}> 检索:</span>
+                        <Input placeholder={'请输入源报表名称'} allowClear
+                            suffix={
+                                <IconFont type="iconsousuo" onClick={() => tableDataSearchHandle('reportName')} />
+                            }
+                            onChange={(e) => {
+                                set_tableDataSearchKeywords(e.target.value);
+                                if (e.target.value.length == 0) {
+                                    set_tableDataFilterParams({
+                                        ...tableDataFilterParams,
+                                        reportName: ''
+                                    });
+                                }
+                            }}
+                            onPressEnter={(e) => {
+
+                                set_tableDataFilterParams({
+                                    ...tableDataFilterParams,
+                                    reportName: (e.target as HTMLInputElement).value
+                                });
+                            }}
+
+                        />
+                    </div>
+                </div>
+                <div className='btnGroup'>
+                    <UpDataActBtn record type='ADD' />
+                </div>
+            </div>
+
+            <div style={{ marginTop: 16 }}>
+                <KCIMTable columns={columns as ProColumns[]} actionRef={tableRef} rowKey='id' params={tableDataFilterParams} request={(params) => getTableData(params)} />
+            </div>
+        </KCIMPagecontainer>
+    )
+}

+ 99 - 0
src/pages/costLibraryManagement/reportMana/reportNavSet/service.ts

@@ -0,0 +1,99 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-03 10:12:52
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+import { request } from 'umi';
+
+//获取table列表数据
+
+export type ReportNavListTableDataType = {
+  id:number,
+  hospId:number,
+  code:number,
+  redirectReportCode:number,
+  redirectReportName:string,
+  reportColumnCode:number,
+  reportColumnName:string,
+  reportCode:number,
+  reportName:string,
+  redirectParameter:string,
+  redirectParameterDisplay:string
+}
+
+
+export const getReportListTableData = (params?:any) => {
+  return request<{
+       current:number;
+       list:ReportNavListTableDataType[];
+       pageSize:number;
+       totalCount:number;
+       totalPage:number;
+  }>('/costAccount/report/getRedirect', {
+    method: 'GET',
+    params:{...params}
+  });
+};
+
+
+//新增报表
+export type AddTableDataType = {
+  redirectReportCode:number,
+  redirectReportName:string,
+  reportColumnCode:number,
+  reportColumnName:string,
+  reportCode:number,
+  reportName:string,
+  redirectParameter:string,
+  redirectParameterDisplay:string
+}
+
+export const addData = (data:AddTableDataType) => {
+  return request('/costAccount/report/addRedirect', {
+    method: 'POST',
+    data
+  });
+};
+
+
+
+
+
+
+//编辑表格数据
+
+export type ManaIndicItemTableRowEditType = {
+  id:number;
+}&AddTableDataType
+
+export const editData = (data:any) => {
+  return request('/costAccount/report/editRedirect', {
+    method: 'POST',
+    data
+  });
+};
+
+//删除表格操作
+export const delData = (id:string) => {
+  return request('/costAccount/report/deleteRedirect', {
+    method: 'POST',
+    params:{id}
+  });
+};
+
+
+
+
+
+
+
+
+
+
+

+ 43 - 0
src/pages/costLibraryManagement/reportMana/reportNavSet/style.less

@@ -0,0 +1,43 @@
+.ReportNavSet {
+  padding: 16px;
+  background: #FFFFFF;
+  border-radius: 4px;
+
+
+  .toolBar {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .filter {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+
+      .filterItem {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .btnGroup {
+      .add {
+        cursor: pointer;
+        display: inline-block;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #FFFFFF;
+        line-height: 24px;
+        padding: 0 14px;
+        background: #3377FF;
+        border-radius: 4px;
+      }
+    }
+
+  }
+}

+ 4 - 4
src/pages/monthlyInfoSearch/empCostDataImport/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-23 15:59:01
+ * @LastEditTime: 2023-11-02 18:40:00
  * @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
  */
@@ -69,9 +69,9 @@ export default function empCostDataImport() {
   const getTableData = async (params:any):Promise<TableDataResponse|any[]> => {
     const resp = await getData({ ...params,...tableDataFilterParams});
     if (resp) {
-      const { list, totalCount, pageSize, totalPage } = resp;
-      if (resp.totalCount == 0 && resp.currPage != 1) {
-        return getTableData({ ...params, current: resp.currPage - 1 });
+      const { list, totalCount, pageSize,current, totalPage } = resp;
+      if (totalCount == 0 && current != 1) {
+        return getTableData({ ...params, current:current - 1 });
       } else {
         return {
           data: list,

+ 20 - 12
src/pages/monthlyInfoSearch/patientChargeItemsImport/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-24 14:13:01
+ * @LastEditTime: 2023-11-03 13:43:37
  * @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
  */
@@ -11,6 +11,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
 
 import {
   ActionType,
+  ProColumns,
   ProFormDependency,
   ProFormDigit,
   ProFormRadio,
@@ -31,6 +32,7 @@ import KCIMPagecontainer from '@/components/KCIMPageContainer';
 import { KCIMTable } from '@/components/KCIMTable';
 import KCIMUpload from '@/components/KCIMUpload';
 import { getTargetDic } from '@/services/auth';
+import { formatMoneyNumber } from '@/utils/format';
 
 
 const IconFont = createFromIconfontCN({
@@ -48,7 +50,7 @@ export default function patientChargeItemsImport() {
   const tableRef = useRef<ActionType>();
   const [totalNum,set_totalNum] = useState(0);
 
-  const columns = [
+  const columns:ProColumns[] = [
     {
       title: '住院号/门诊号',
       dataIndex: 'visitNo',
@@ -107,7 +109,7 @@ export default function patientChargeItemsImport() {
     },
     {
       title: '数量',
-      dataIndex: 'amount',
+      dataIndex: 'num',
     },
     {
       title: '单价',
@@ -115,7 +117,10 @@ export default function patientChargeItemsImport() {
     },
     {
       title: '金额',
-      dataIndex: 'cost',
+      dataIndex: 'amount',
+      renderText(num) {
+          return formatMoneyNumber(num);
+      },
     },
     {
       title: '费用发生时间',
@@ -147,8 +152,8 @@ export default function patientChargeItemsImport() {
   };
 
   const getTotalNum = async ()=>{
-      const resp = await getTotalNumReq(computeDate);
-      if(resp){
+      const resp = await getTotalNumReq({computeDate,itemType:tableDataFilterParams.itemType,departmentName:tableDataFilterParams.departmentName});
+      if(resp||resp == 0){
         set_totalNum(resp);
       }
   }
@@ -209,8 +214,12 @@ export default function patientChargeItemsImport() {
     );
   };
 
-  useEffect(() => {
+  useEffect(()=>{
     getTotalNum();
+  },[tableDataFilterParams])
+
+  useEffect(() => {
+
   }, []);
 
   return (
@@ -253,10 +262,9 @@ export default function patientChargeItemsImport() {
                   style={{ width: 160, marginRight: 16 }}
                   request={async () => {
                     const resp = await getTargetDic('CHARGE_ITEM_TYPE');
-                    const { data, status } = resp;
-                    if (status == 200) {
-                      const { dataVoList } = data;
-                      return dataVoList.map((a:any) => ({ label: a.name, value: a.value }));
+                    if (resp) {
+                      const { dataVoList } = resp;
+                      return dataVoList.map((a:any) => ({ label: a.name, value: a.code }));
                     }
                     return [];
                   }}
@@ -302,7 +310,7 @@ export default function patientChargeItemsImport() {
         </div>
         <div className="btnGroup">{importData()}</div>
       </div>
-      <div className='total'>总金额:{totalNum}</div>
+      <div className='total'>总金额:{formatMoneyNumber(totalNum)}</div>
       <div style={{ marginTop: 16 }}>
         <KCIMTable
           columns={columns}

+ 3 - 3
src/pages/monthlyInfoSearch/patientChargeItemsImport/service.js

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 16:31:27
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-20 11:15:06
+ * @LastEditTime: 2023-10-27 10:32:21
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -22,10 +22,10 @@ export const getData = (params) => {
 };
 
 //获取总数
-export const getTotalNumReq = (computeDate) => {
+export const getTotalNumReq = (params) => {
   return request('/costAccount/computeImport/getComputeTotal', {
     method: 'GET',
-    params:{computeDate}
+    params:{...params}
   });
 };
 

+ 22 - 5
src/pages/monthlyInfoSearch/patientInfoImport/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-23 16:05:32
+ * @LastEditTime: 2023-10-30 11:18:10
  * @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
  */
@@ -23,7 +23,7 @@ import locale from 'antd/es/date-picker/locale/zh_CN';
 import KCIMPagecontainer from '@/components/KCIMPageContainer';
 import { KCIMTable } from '@/components/KCIMTable';
 import KCIMUpload from '@/components/KCIMUpload';
-import { ActionType } from '@ant-design/pro-components';
+import { ActionType, ProColumns } from '@ant-design/pro-components';
 
 
 const IconFont = createFromIconfontCN({
@@ -38,23 +38,27 @@ export default function patientInfoImport() {
   const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
   const tableRef = useRef<ActionType>();
 
-  const columns = [
+  const columns:ProColumns[] = [
     {
       title: '住院号/门诊号',
       dataIndex: 'visitNo',
+      ellipsis:true
     },
     {
       title: '病人ID',
       dataIndex: 'patientNo',
+      ellipsis:true
     },
     {
       title: '患者姓名',
       dataIndex: 'name',
+      ellipsis:true
     },
     {
       title: '就诊类别',
       dataIndex: 'type',
-      renderText(type: number, record: any, index: any, action: any) {
+      ellipsis:true,
+      renderText(type: number) {
         if(type==1)return '门诊';
         if(type==3)return '住院';
         if(type==2)return '急诊'
@@ -63,18 +67,22 @@ export default function patientInfoImport() {
     {
       title: '科室代码',
       dataIndex: 'departmentCode',
+      ellipsis:true
     },
     {
       title: '科室名称',
       dataIndex: 'departmentName',
+      ellipsis:true
     },
     {
       title: '主诊断代码',
       dataIndex: 'primaryDiagCode',
+      ellipsis:true
     },
     {
       title: '主诊断名称',
       dataIndex: 'primaryDiagName',
+      ellipsis:true
     },
     {
       title: '次诊断代码',
@@ -89,10 +97,12 @@ export default function patientInfoImport() {
     {
       title: '主手术/操作代码',
       dataIndex: 'primaryOperationCode',
+      ellipsis:true
     },
     {
       title: '主手术/操作名称',
       dataIndex: 'primaryOperationName',
+      ellipsis:true
     },
     {
       title: '次手术/操作代码',
@@ -107,30 +117,37 @@ export default function patientInfoImport() {
     {
       title: 'DRG/DIP分组代码',
       dataIndex: 'groupCode',
+      ellipsis:true
     },
     {
       title: 'DRG/DIP分组名称',
       dataIndex: 'groupMame',
+      ellipsis:true
     },
     {
       title: '临床路径代码',
       dataIndex: 'clinicalPathwayCode',
+      ellipsis:true
     },
     {
       title: '临床路径名称',
       dataIndex: 'clinicalPathwayName',
+      ellipsis:true
     },
     {
       title: '入院日期',
       dataIndex: 'inHospitalTime',
+      ellipsis:true
     },
     {
       title: '出院日期',
       dataIndex: 'outHospitalTime',
+      ellipsis:true
     },
     {
       title: '住院天数',
       dataIndex: 'inHospitalDays',
+      ellipsis:true
     },
   ];
 
@@ -264,7 +281,7 @@ export default function patientInfoImport() {
               />
           </div>
           <div className='filterItem' style={{ marginLeft: 16, width: 205 }}>
-              <span className='label' style={{ whiteSpace: 'nowrap' }}> 患者名:</span>
+              <span className='label' style={{ whiteSpace: 'nowrap' }}> 患者名:</span>
               <Input placeholder={'请输入'} allowClear
                   suffix={
                       <IconFont type="iconsousuo" style={{ color: '#99A6BF' }} onClick={() => tableDataSearchHandle('patientName')} />

+ 332 - 0
src/pages/reportCheck/report/index.tsx

@@ -0,0 +1,332 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-01-04 14:12:31
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-08 15:51:40
+ * @FilePath: /BudgetManaSystem/src/pages/budgetMana/oneBatch/index.tsx
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+import { ActionType, ProColumns } from '@ant-design/pro-components';
+import { Space, Dropdown, MenuProps, DatePicker } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+import { getData, getRedirReportData } from './service';
+
+
+import './style.less';
+
+import { useParams } from '@umijs/max';
+import { DownOutlined } from '@ant-design/icons';
+
+import exportTableToExcel from '@/utils/tableToExcel';
+
+
+import 'moment/locale/zh-cn';
+import locale from 'antd/es/date-picker/locale/zh_CN';
+import moment from 'moment';
+import { formatMoneyNumber } from '@/utils/format';
+
+import KCIMPagecontainer from '@/components/KCIMPageContainer';
+import { KCIMTable } from '@/components/KCIMTable';
+import { getStringWidth } from '@/utils/tooljs';
+
+
+
+// const {search} = locatio
+
+
+const ReportExport = () => {
+
+
+  const { reportCode: urlReportCode } = useParams();
+
+  const [tableColumn, set_tableColumn] = useState<ProColumns[] | any[]>([]);
+
+  const [tableData, set_tableData] = useState<any[]>([]);
+
+  const [currentComputeDate, set_currentComputeDate] = useState<string | undefined>();
+
+  const [breadCrumbList, set_breadCrumbList] = useState<any[]>([]);
+
+  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>({ reportCode: urlReportCode });
+
+  const tableRef = useRef<ActionType>();
+
+  const [tableH, set_tableH] = useState(0);
+
+  const [step, set_step] = useState(0);
+
+  const [reportName, set_reportName] = useState('')
+
+  const reportJumphandle = (reportData: any) => {
+
+    let parameter: { [key: string]: any } = {};
+    const { redirectParameter = undefined } = reportData;
+    const _step = step + 1;
+
+    if (redirectParameter) {
+      const tempArr = redirectParameter.split('|');
+      tempArr.forEach((element: string) => {
+        parameter[`${element}`] = reportData[`${element}`]
+      });
+    }
+
+    set_breadCrumbList(
+      [...breadCrumbList,
+      {
+        index: _step,
+        name: reportData[`report_name`] || reportData[`redirectReportName`],
+        params: {
+          reportCode: reportData.redirectReportCode,
+          parameter: {
+            compute_date: currentComputeDate,
+            ...parameter
+          }
+        }
+      }
+      ]
+    );
+
+    set_step(_step);
+
+    set_tableDataFilterParams({
+      ...tableDataFilterParams, reportCode: reportData.redirectReportCode, parameter: {
+        compute_date: currentComputeDate,
+        ...parameter
+      }
+    })
+  }
+
+
+  const getTableData = async (params: any, sort: any, filter: any) => {
+
+    const { reportCode, parameter } = params;
+
+    let resp: any = undefined;
+
+    if (step != 0) {
+      //报表跳转
+      resp = await getRedirReportData(
+        reportCode,
+        parameter
+      );
+    }
+
+    if (step == 0) {
+      //首次获取表格数据
+      resp = await getData(
+        reportCode,
+        parameter
+      );
+    }
+
+    if (resp) {
+
+      const { title, data: assignmentData, reportName } = resp;
+      set_reportName(reportName);
+      const columns: ProColumns[] = title.map((item: any, index: number) => {
+        return {
+          title: item.name,
+          dataIndex: `${item.columnName}`,
+          key: `${item.columnName}`,
+          width:getStringWidth(item.name,'14px'),
+          ellipsis: true,
+          fixed: item.freeze?true:false,
+          hideInTable: item.hide,
+          sorter:item.sortStatus?(a:any, b:any) => {
+            if(item.dataType == 3){
+                //数值
+                return b[`${item.columnName}`] - (a[`${item.columnName}`]);
+            }else{
+              return b[`${item.columnName}`].localeCompare(a[`${item.columnName}`]);
+            }
+          }:undefined,
+          renderText:(_:string|number, record:any) => {
+    
+            if (item.redirect) {
+              if (item.redirectData && item.redirectData.length > 1) {
+
+                const items: MenuProps['items'] = [
+                  ...(item.redirectData.map((a: any, index: number) => ({
+                    key: index,
+                    label: (
+                      <a onClick={() => reportJumphandle({ ...item, ...record, ...a })}>
+                        {a.redirectReportName}
+                      </a>
+                    ),
+                  })))
+                ];
+
+                return <Dropdown menu={{ items }}>
+                  <a onClick={(e) => e.preventDefault()}>
+                    <Space>
+                      {(item.dataType && item.dataType == 2 && _) ? formatMoneyNumber(Number(Number(_).toFixed(2))) : _}
+                      <DownOutlined />
+                    </Space>
+                  </a>
+                </Dropdown>
+              } else {
+                return <a className='active' onClick={() => reportJumphandle({ ...item.redirectData[0], ...record })}>{(item.dataType && item.dataType == 2 && _) ? Number(Number(_).toFixed(2)) : _}</a>
+              }
+            }
+
+            return <span >{(item.dataType && item.dataType == 2 && _) ? formatMoneyNumber(Number(Number(_).toFixed(2))) : _}</span>
+          }
+
+        }
+      });
+
+      set_tableColumn([...columns]);
+
+      const data = assignmentData.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].columnName}`] = b.value
+          }
+        });
+
+
+        return { ...item, ...rowData, id: Math.random(), columns }
+      });
+      set_tableData(data);
+      return {
+        data,
+        success: true
+      }
+
+    }
+    return []
+  }
+
+
+
+
+  const handleResize = (e: any) => {
+    const wH = e.target.innerHeight;
+    const tableHeight = wH - 290;
+    set_tableH(tableHeight);
+  }
+
+  function doResize() {
+    setTimeout(() => {
+      const ev: any = new Event('resize');
+      window.dispatchEvent(ev);
+    }, 0)
+  }
+
+  const exportHandle = () => {
+
+    //const headers = { name: '姓名', age: '年龄', city: '城市' };
+    let headers: { [key: string]: any } = {};
+    let data: any[] = [];
+    tableColumn.forEach(a => {
+      if (a.hideInTable != 1) {
+        headers[`${a.dataIndex}`] = a.title;
+      }
+    });
+
+    tableData.forEach(b => {
+      let _temp: { [key: string]: any } = {};
+      Object.keys(headers).forEach(key => {
+        _temp[`${key}`] = b[`${key}`]
+      });
+      data.push(_temp);
+    });
+
+    //console.log({tableColumn,headers,tableData,data});
+    const excelTableData = [
+      ...data
+    ];
+
+    exportTableToExcel(excelTableData, tableColumn as any[], reportName);
+  }
+
+
+  //面包屑跳转
+  const switchHandle = (data: any) => {
+    console.log({ data });
+    set_step(data.index);
+    const _breadCrumbList = breadCrumbList.filter((a: any) => a.index <= data.index);
+    set_breadCrumbList([..._breadCrumbList]);
+    set_tableDataFilterParams({ ...tableDataFilterParams, ...data.params });
+  }
+
+
+  useEffect(() => {
+    // 在这里处理路由参数变化的逻辑
+    if (currentComputeDate) {
+
+      set_tableDataFilterParams({ reportCode: urlReportCode, parameter: { compute_date: currentComputeDate } });
+      set_breadCrumbList([{
+        name: '首页',
+        index: 0,
+        params: { reportCode: urlReportCode, parameter: { compute_date: currentComputeDate } }
+      }])
+
+    }
+
+  }, [urlReportCode, currentComputeDate]);
+
+
+  useEffect(() => {
+
+    set_currentComputeDate(`${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString().padStart(2, '0')}`);
+
+    window.addEventListener('resize', (e) => handleResize(e)) //监听窗口大小改变
+    doResize();
+
+    return () => {
+      window.removeEventListener('resize', (e) => handleResize(e))
+    }
+  }, [])
+
+
+  return (
+    <KCIMPagecontainer className='ReportTemplate' title={false}>
+
+      {
+        breadCrumbList.length > 1 && <div className='breadcrumb'>
+          {
+            breadCrumbList.map((item: any, index: number) => {
+              return (
+                <>
+                  <span className={index != step ? 'tab' : 'tab actived'} key={index} onClick={() => { index != step && switchHandle(item) }}>{item.name}</span>{index == breadCrumbList.length - 1 ? '' : <span style={{ color: '#7A8599' }}> / </span>}
+                </>
+              )
+            })
+          }
+        </div>
+      }
+      <div className='contentWrap'>
+        {currentComputeDate && (<div className='search'>
+          <span>核算年月:</span>
+          <DatePicker
+            onChange={(data, dateString) => {
+              set_tableDataFilterParams({ ...tableDataFilterParams, parameter: { ...tableDataFilterParams.parameter, compute_date: dateString } });
+            }}
+            allowClear={false}
+            picker='month'
+            locale={locale}
+            defaultValue={moment(currentComputeDate, 'YYYY-MM')}
+            format='YYYY-MM' placeholder="请选择核算年月" />
+        </div>)}
+        <div className='export' onClick={() => exportHandle()}>导出</div>
+
+        <div className='content'>
+          {currentComputeDate && <KCIMTable actionRef={tableRef} rowKey='id' pagination={false} columns={tableColumn as ProColumns[]}
+            params={tableDataFilterParams}
+            scroll={{ x: 100 * tableColumn.length, y: tableH }}
+            request={(params, sort, filter) => getTableData(params, sort, filter)}
+          />}
+        </div>
+      </div>
+    </KCIMPagecontainer>
+  )
+}
+
+export default ReportExport

+ 46 - 0
src/pages/reportCheck/report/service.ts

@@ -0,0 +1,46 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-01-04 13:59:26
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2023-11-07 11:20:33
+ * @FilePath: /BudgetManaSystem/src/pages/budgetMana/personnelSalaryBudget/service.ts
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+
+
+
+
+
+
+
+import { request } from '@@/plugin-request'
+
+
+
+export const getData = (reportCode:string,parameter:any)=>{
+
+    return request('/costAccount/report/search', {
+         method:'POST',
+         data:{
+            reportCode,
+            parameter
+        }
+    })
+}
+
+
+//获取跳转报表数据
+export const getRedirReportData = (reportCode:string,parameter:any)=>{
+    return request('/costAccount/report/redirect', {
+        method:'POST',
+        data:{
+            reportCode,
+            parameter
+        }
+   })
+}
+
+
+
+

+ 64 - 0
src/pages/reportCheck/report/style.less

@@ -0,0 +1,64 @@
+.ReportTemplate {
+    .breadcrumb {
+        margin-top: 8px;
+        margin-bottom: 16px;
+        height: 14px;
+
+        .tab {
+            font-size: 14px;
+            color: #7A8599;
+            cursor: pointer;
+            padding: 4px;
+            &:hover {
+                background: #E6EAF2;
+                border-radius: 4px;
+            }
+
+            &.actived {
+                color: #17181A;
+                &:hover {
+                    cursor: default;
+                    color: #17181A;
+                    text-decoration: none;
+                    background: transparent;
+                }
+            }
+        }
+    }
+
+    .contentWrap {
+        position: relative;
+        padding: 16px;
+        border-radius: 4px;
+        background: #fff;
+
+        .export {
+            position: absolute;
+            top: 16px;
+            right: 16px;
+            width: 56px;
+            height: 24px;
+            color: #fff;
+            text-align: center;
+            line-height: 24px;
+            cursor: pointer;
+            background: #3377FF;
+            border-radius: 4px;
+        }
+
+        .content {
+            position: relative;
+            padding-top: 8px;
+
+            .bms-ant-tabs-nav {
+                &::before {
+                    border-bottom: none !important;
+                }
+            }
+
+            .bms-ant-table-body {
+                max-height: calc(100vh - 210px) !important;
+            }
+        }
+    }
+}

+ 31 - 8
src/pages/static/index.tsx

@@ -2,14 +2,14 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-10-26 11:12:59
+ * @LastEditTime: 2023-10-26 17:52:50
  * @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 {Skeleton } from 'antd';
+import { Skeleton } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { useLocation } from 'umi';
 
@@ -30,30 +30,53 @@ function getQueryParams() {
 }
 
 
+
 export default function StaticPage() {
 
   const [specialPageUrl, setspecialPageUrl] = useState<string | undefined>(undefined);
   const [loading, setloading] = useState(false);
+  const { softUrl } = getQueryParams();
+  const location = useLocation();
+  const [scale,set_scale] = useState(0.5);
+  const [translate,set_translate] = useState({x:0,y:0});
 
 
   const onLoadhandle = () => {
     setloading(false);
   };
 
+  const adjustIframeScale = ()=>{
+    const desiredWidth = 1200
+    const windowWidth = window.innerWidth - 232;
+    let scale = windowWidth / desiredWidth;
+    // scale = Math.min(scale, 1); // 限制最大缩放比例为1
+    const  translateX = (windowWidth - desiredWidth * scale) / 2 / scale;
+    const translateY = 0; // 如果需要,也可以计算垂直平移
+    set_translate({x:translateX,y:translateY});
+    set_scale(scale);
+  }
+
+
   useEffect(() => {
     setloading(true);
-    const {softUrl} = getQueryParams();
-    // console.log({history,location,softUrl});
-    setspecialPageUrl(softUrl?softUrl:'');
-    
-  }, []);
+    setspecialPageUrl(softUrl ? softUrl : '');
+
+  }, [location]);
+
+  useEffect(() => {
+    adjustIframeScale();
+    window.addEventListener('resize', adjustIframeScale);
+    return ()=>{
+      window.removeEventListener('resize', adjustIframeScale);
+    }
+  }, [])
 
   return (
     <KCIMPagecontainer className="StaticPage" title={false}>
       <Skeleton loading={loading} paragraph={{ rows: 50 }} active />
       <iframe
         onLoad={() => onLoadhandle()}
-        style={{ width: '100%', height: '90vh', border: 'none' }}
+        style={{ width: '100%', height: '90vh', border: 'none',transformOrigin:'top left',paddingLeft:100,overflow:'hidden'}}
         src={specialPageUrl}
       ></iframe>
     </KCIMPagecontainer>

+ 2 - 2
src/utils/format.ts

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2022-12-14 14:14:32
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-06-08 15:27:39
+ * @LastEditTime: 2023-11-07 16:00:41
  * @FilePath: /BudgetManaSystem/src/utils/format.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -14,7 +14,7 @@ export function trim(str: string) {
 //金额数字转换
 export function formatMoneyNumber(num:number) {
   if (typeof num !== 'number' || isNaN(num)) {
-    return '-';
+    return num;
   } 
   return new Intl.NumberFormat('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 2 }).format(num);
 }

+ 70 - 1
src/utils/tooljs.ts

@@ -2,12 +2,16 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-02-20 14:31:06
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-09-21 14:38:08
+ * @LastEditTime: 2023-11-08 15:49:40
  * @FilePath: /BudgetManaSystem/src/utils/tooljs.js
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
 
 
+import axios from 'axios';
+
+
+
 let parent:any = undefined;
 
 export const getDeepestTreeData:any= (tree:any,childrenName:string)=>{
@@ -188,6 +192,71 @@ export const searchLeaves = (nodes:any[], keywords:string|undefined, keyName: st
 }
 
 
+//导入按钮的下载模板
+
+export const downloadTemplateReq = (pathStr:string) => {
+
+
+  let path = `/gateway${pathStr}`;
+
+  const userData = localStorage.getItem('userData');
+  const { token = '' } = JSON.parse(userData as string);
+
+  axios({
+      method: 'get',
+      url: path,
+      responseType: 'blob',
+      headers: { token },
+  })
+      .then(function (response) {
+          //console.log({ 'chunk': response });
+          const filename = decodeURI(response.headers["content-disposition"]);
+          const objectUrl = URL.createObjectURL(
+              new Blob([response.data], {
+                  type: 'application/vnd.ms-excel',
+              })
+          )
+          const link = document.createElement('a')
+          // 设置导出的文件名称
+          link.download = `${filename}` + '.xls'
+          link.style.display = 'none'
+          link.href = objectUrl
+          link.click()
+          document.body.appendChild(link)
+
+      });
+
+
+
+}
+
+
+
+//计算字符串长度px
+
+export const getStringWidth = (str:string, font:string) => {
+  // 创建一个临时元素
+  var tempDiv = document.createElement('div');
+  tempDiv.style.position = 'absolute';
+  tempDiv.style.visibility = 'hidden';
+  tempDiv.style.height = 'auto';
+  tempDiv.style.width = 'auto';
+  tempDiv.style.whiteSpace = 'nowrap';
+  tempDiv.style.font = font; // 设置字体样式,例如 "12px Arial"
+  tempDiv.textContent = str;
+
+  // 将元素添加到文档中,以便进行测量
+  document.body.appendChild(tempDiv);
+
+  // 获取元素的宽度
+  var width = tempDiv.clientWidth;
+
+  // 移除临时元素
+  document.body.removeChild(tempDiv);
+
+  return width;
+}
+
 
 
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3 - 3
src/utils/zhongtaiC.js


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است