Browse Source

9月29号之前所有功能

code4eat 3 năm trước cách đây
mục cha
commit
a8a826771d
81 tập tin đã thay đổi với 7383 bổ sung592 xóa
  1. 3 1
      config/defaultSettings.ts
  2. 90 7
      config/routes.ts
  3. 29 1
      mock/articleManagement.ts
  4. 49 0
      mock/generalSetting.ts
  5. 154 0
      mock/qualityRating.ts
  6. 1 0
      package.json
  7. 27 9
      src/app.tsx
  8. 259 0
      src/components/CAUpload/index.jsx
  9. 79 27
      src/components/MccsClickableTabs/index.less
  10. 74 19
      src/components/MccsClickableTabs/index.tsx
  11. 10 5
      src/components/MccsClickableTabs/typings.d.ts
  12. 11 3
      src/components/MccsDrawerForm/index.tsx
  13. 2 1
      src/components/MccsDrawerForm/typings.d.ts
  14. 63 0
      src/components/MccsEditableTable/index.tsx
  15. 28 0
      src/components/MccsEditableTable/typings.d.ts
  16. 88 81
      src/components/MccsFileTree/index.tsx
  17. 6 5
      src/components/MccsModal/index.tsx
  18. 29 21
      src/components/MccsRecordList/index.tsx
  19. 15 12
      src/components/MccsRecordList/typings.d.ts
  20. 2 2
      src/components/MccsTable/index.tsx
  21. 8 0
      src/components/MccsUpload/README.md
  22. 0 0
      src/components/MccsUpload/index.less
  23. 42 0
      src/components/MccsUpload/index.tsx
  24. 20 0
      src/components/MccsUpload/typings.d.ts
  25. 15 22
      src/components/RightContent/AvatarDropdown.tsx
  26. 13 0
      src/env.ts
  27. 19 1
      src/global.less
  28. 4 4
      src/global.tsx
  29. 9 4
      src/models/allModels.ts
  30. 6 0
      src/pages/DataManagement/publicData/index.less
  31. 470 0
      src/pages/DataManagement/publicData/index.tsx
  32. 161 0
      src/pages/DataManagement/publicData/model.ts
  33. 129 0
      src/pages/DataManagement/publicData/serve.ts
  34. 46 0
      src/pages/DataManagement/publicData/typings.d.ts
  35. 4 21
      src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/index.tsx
  36. 7 1
      src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/typings.d.ts
  37. 21 16
      src/pages/GradeHospitalAccreditation/accreditationDetail/index.less
  38. 139 98
      src/pages/GradeHospitalAccreditation/accreditationDetail/index.tsx
  39. 16 9
      src/pages/GradeHospitalAccreditation/accreditationDetail/model.ts
  40. 18 0
      src/pages/GradeHospitalAccreditation/articleManagement/index.less
  41. 290 98
      src/pages/GradeHospitalAccreditation/articleManagement/index.tsx
  42. 274 65
      src/pages/GradeHospitalAccreditation/articleManagement/model.ts
  43. 69 8
      src/pages/GradeHospitalAccreditation/articleManagement/server.ts
  44. 100 50
      src/pages/GradeHospitalAccreditation/articleManagement/typings.d.ts
  45. 61 0
      src/pages/GradeHospitalAccreditation/ledgerUpload/index.less
  46. 287 0
      src/pages/GradeHospitalAccreditation/ledgerUpload/index.tsx
  47. 204 0
      src/pages/GradeHospitalAccreditation/ledgerUpload/model.ts
  48. 64 0
      src/pages/GradeHospitalAccreditation/ledgerUpload/server.ts
  49. 62 0
      src/pages/GradeHospitalAccreditation/ledgerUpload/typings.d.ts
  50. 6 0
      src/pages/KeepImprove/departmentIssueRank/index.less
  51. 29 0
      src/pages/KeepImprove/departmentIssueRank/index.tsx
  52. 6 0
      src/pages/KeepImprove/departmentScoreRank/index.less
  53. 29 0
      src/pages/KeepImprove/departmentScoreRank/index.tsx
  54. 79 0
      src/pages/KeepImprove/qualityRating/index.less
  55. 289 0
      src/pages/KeepImprove/qualityRating/index.tsx
  56. 28 0
      src/pages/KeepImprove/qualityRating/serve.ts
  57. 6 0
      src/pages/KeepImprove/questionGather/index.less
  58. 29 0
      src/pages/KeepImprove/questionGather/index.tsx
  59. 6 0
      src/pages/KeepImprove/questionGatherAndRevise/index.less
  60. 29 0
      src/pages/KeepImprove/questionGatherAndRevise/index.tsx
  61. 306 0
      src/pages/PlatformMana/districtMana/index.jsx
  62. 59 0
      src/pages/PlatformMana/districtMana/service.js
  63. 121 0
      src/pages/PlatformMana/districtMana/updateForm.jsx
  64. 19 0
      src/pages/PlatformMana/generalSetting/index.less
  65. 394 0
      src/pages/PlatformMana/generalSetting/index.tsx
  66. 66 0
      src/pages/PlatformMana/generalSetting/serve.ts
  67. 31 0
      src/pages/PlatformMana/generalSetting/typings.d.ts
  68. 318 0
      src/pages/PlatformMana/menuManage/index.js
  69. 69 0
      src/pages/PlatformMana/menuManage/service.js
  70. 102 0
      src/pages/PlatformMana/menuManage/updateForm.jsx
  71. 137 0
      src/pages/PlatformMana/roleManage/component/drawer.jsx
  72. 7 0
      src/pages/PlatformMana/roleManage/component/style.less
  73. 409 0
      src/pages/PlatformMana/roleManage/index.js
  74. 100 0
      src/pages/PlatformMana/roleManage/service.js
  75. 52 0
      src/pages/PlatformMana/roleManage/updateForm.jsx
  76. 270 0
      src/pages/PlatformMana/userMana/index.js
  77. 60 0
      src/pages/PlatformMana/userMana/service.js
  78. 81 0
      src/pages/PlatformMana/userMana/updateForm.jsx
  79. 2 1
      src/pages/user/Login/index.tsx
  80. 524 0
      src/test.html
  81. 143 0
      src/utils.js

+ 3 - 1
config/defaultSettings.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-03 14:28:27
- * @LastEditTime: 2021-09-03 17:17:03
+ * @LastEditTime: 2021-09-26 18:11:53
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/config/defaultSettings.ts
@@ -28,4 +28,6 @@ const Settings: LayoutSettings & {
   iconfontUrl: '',
 };
 
+
+
 export default Settings;

+ 90 - 7
config/routes.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-03 14:28:27
- * @LastEditTime: 2021-09-16 09:58:25
+ * @LastEditTime: 2021-09-29 18:34:00
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/config/routes.ts
@@ -27,16 +27,43 @@ export default [
     ],
   },
   {
-    path: '/welcome',
-    name: 'welcome',
+    path: '/PlatformMana',
+    name: '平台系统管理',
     icon: 'smile',
-    component: './Welcome',
+    routes: [
+      {
+        path: '/PlatformMana/generalSetting',
+        name: '通用设置',
+        component: './PlatformMana/generalSetting/index',
+      },
+      {
+        path: '/PlatformMana/userMana',
+        name: '用户管理',
+        component: './PlatformMana/userMana/index',
+      },
+      {
+        name: '角色管理',
+        path: '/PlatformMana/roleManage',
+        component: './PlatformMana/roleManage/index',
+      },
+      {
+        name: '菜单管理',
+        path: '/PlatformMana/menuManage',
+        component: './PlatformMana/menuManage/index',
+      },
+      // {
+      //   path: '/PlatformMana/districtMana',
+      //   name: '院区管理',
+      //   icon: 'InsertRowLeftOutlined',
+      //   component: './PlatformMana/districtMana/index',
+      // },
+    ],
   },
   {
     path: '/GradeHospitalAccreditation',
     name: '等级医院评审',
     icon: 'smile',
-    routes:[
+    routes: [
       {
         path: '/GradeHospitalAccreditation/accreditationDetail',
         name: '评审细则',
@@ -49,11 +76,67 @@ export default [
         icon: 'smile',
         component: './GradeHospitalAccreditation/articleManagement/index',
       },
-    ]
+      {
+        path: '/GradeHospitalAccreditation/ledgerUpload',
+        name: '台账上传',
+        icon: 'smile',
+        component: './GradeHospitalAccreditation/ledgerUpload/index',
+      },
+    ],
+  },
+  {
+    path: '/DataManagement',
+    name: '资料管理',
+    icon: 'smile',
+    routes: [
+      {
+        path: '/DataManagement/publicData',
+        name: '公共资料',
+        icon: 'smile',
+        component: './DataManagement/publicData/index',
+      },
+    ],
+  },
+  {
+    path: '/KeepImprove',
+    name: '持续改进',
+    icon: 'smile',
+    routes: [
+      {
+        path: '/KeepImprove/qualityRating',
+        name: '质量评级',
+        icon: 'smile',
+        component: './KeepImprove/qualityRating/index',
+      },
+      {
+        path: '/KeepImprove/questionGatherAndRevise',
+        name: '问题汇总与整改',
+        icon: 'smile',
+        component: './KeepImprove/questionGatherAndRevise/index',
+      },
+      {
+        path: '/KeepImprove/departmentIssueRank',
+        name: '单位问题排名',
+        icon: 'smile',
+        component: './KeepImprove/departmentIssueRank/index',
+      },
+      {
+        path: '/KeepImprove/departmentScoreRank',
+        name: '单位得分排名',
+        icon: 'smile',
+        component: './KeepImprove/departmentScoreRank/index',
+      },
+      {
+        path: '/KeepImprove/questionGather',
+        name: '问题汇总',
+        icon: 'smile',
+        component: './KeepImprove/questionGather/index',
+      },
+    ],
   },
   {
     path: '/',
-    redirect: '/welcome',
+    redirect: '/',
   },
   {
     component: './404',

+ 29 - 1
mock/articleManagement.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 14:40:58
- * @LastEditTime: 2021-09-15 18:18:32
+ * @LastEditTime: 2021-09-22 09:22:38
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/mock/articleManagement.ts
@@ -173,10 +173,38 @@ const getDepartmentList = (req: Request, res: Response, u: string)=>{
       return res.json(result); 
 }
 
+const getSelfEvaluation = (req: Request, res: Response, u: string)=>{
+  const result = {
+    data:{
+        totalCount:0,
+        pageSize:1,
+        current:1,
+        list:[
+            {
+                id:1,
+                selfEvaluation:'C',
+                userName:'李四',
+                createDate:'2021-09-22 09:19:20',    
+            },
+            {
+              id:2,
+              selfEvaluation:'A',
+              userName:'李丽',
+              createDate:'2021-09-22 09:19:20',    
+            },
+        ]
+    },
+    success: true,
+    status:200,
+  };
+  return res.json(result); 
+}
+
 
 
 export default {
   'GET /api/pfm/reviewRules/getAllTree': getList,
   'GET /api/pfm/reviewArticle/list': getRuleDetailList,
   'GET /api/pfm/sysdepartment/getSysDepartmentList': getDepartmentList,
+  'GET /api/pfm/pfmarticlehistory/getSelfEvaluation': getSelfEvaluation,
 };

+ 49 - 0
mock/generalSetting.ts

@@ -0,0 +1,49 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 11:03:40
+ * @LastEditTime: 2021-09-27 11:45:41
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/mock/generalSetting.ts
+ */
+
+
+
+
+
+import { Request, Response } from 'express';
+
+
+const getTableData = (req: Request, res: Response, u: string)=>{
+  const result = {
+    data:[
+        {
+            id:'序号1',
+            generalName:'名称',
+            categoryType:'组别类型',
+        },
+        {
+            id:'序号2',
+            generalName:'名称',
+            categoryType:'组别类型',
+        },
+        {
+            id:'序号3',
+            generalName:'名称',
+            categoryType:'组别类型',
+        },
+        
+    ],
+    success: true,
+    status:200,
+  };
+  return res.json(result); 
+}
+
+
+
+
+
+export default {
+  'GET /api/pfm/getTypeTableData': getTableData,
+};

+ 154 - 0
mock/qualityRating.ts

@@ -0,0 +1,154 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 09:24:05
+ * @LastEditTime: 2021-09-27 10:13:29
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/mock/qualityRating.ts
+ */
+
+
+/*
+ * @Author: your name
+ * @Date: 2021-09-14 14:40:58
+ * @LastEditTime: 2021-09-22 09:22:38
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/mock/articleManagement.ts
+ */
+
+
+
+
+
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { Request, Response } from 'express';
+
+
+const getTableData = (req: Request, res: Response, u: string)=>{
+  const result = {
+    data:[
+        {
+            typeLevel:'C级',
+            require:'≥95%',
+            site:'97%',
+            target:'95%',
+            self:'90%',
+            system:'97%'
+        },
+        {
+            typeLevel:'C级',
+            require:'≥95%',
+            site:'97%',
+            target:'95%',
+            self:'90%',
+            system:'97%'
+        },
+        {
+            typeLevel:'C级',
+            require:'≥95%',
+            site:'97%',
+            target:'95%',
+            self:'90%',
+            system:'97%'
+        },
+        {
+            typeLevel:'C级',
+            require:'≥95%',
+            site:'97%',
+            target:'95%',
+            self:'90%',
+            system:'97%'
+        }
+    ],
+    success: true,
+    status:200,
+  };
+  return res.json(result); 
+}
+
+const getMapData = (req: Request, res: Response, u: string)=>{
+    const result = {
+        data:[
+            {
+                labelName:'现场查核',
+                qualityTypeList:[
+                    {
+                        levelType:'A级',
+                        levelValue:50
+                    },
+                    {
+                        levelType:'B级',
+                        levelValue:70
+                    },
+                    {
+                        levelType:'C级',
+                        levelValue:30
+                    }
+                ]
+            },
+            {
+                labelName:'目标',
+                qualityTypeList:[
+                    {
+                        levelType:'A级',
+                        levelValue:50
+                    },
+                    {
+                        levelType:'B级',
+                        levelValue:70
+                    },
+                    {
+                        levelType:'C级',
+                        levelValue:30
+                    }
+                ]
+            },
+            {
+                labelName:'自评',
+                qualityTypeList:[
+                    {
+                        levelType:'A级',
+                        levelValue:50
+                    },
+                    {
+                        levelType:'B级',
+                        levelValue:70
+                    },
+                    {
+                        levelType:'C级',
+                        levelValue:30
+                    }
+                ]
+            },
+            {
+                labelName:'系统评分',
+                qualityTypeList:[
+                    {
+                        levelType:'A级',
+                        levelValue:50
+                    },
+                    {
+                        levelType:'B级',
+                        levelValue:70
+                    },
+                    {
+                        levelType:'C级',
+                        levelValue:30
+                    }
+                ]
+            },
+
+        ],
+        success: true,
+        status:200,
+      };
+      return res.json(result); 
+}
+
+
+
+export default {
+  'GET /api/pfm/quality/getStatistics': getTableData,
+  'GET /api/pfm/quality/ratingAnalysis': getMapData,
+};

+ 1 - 0
package.json

@@ -51,6 +51,7 @@
     "not ie <= 10"
   ],
   "dependencies": {
+    "@ant-design/charts": "^1.2.13",
     "@ant-design/icons": "^4.5.0",
     "@ant-design/pro-card": "^1.14.17",
     "@ant-design/pro-descriptions": "^1.6.8",

+ 27 - 9
src/app.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-03 14:28:27
- * @LastEditTime: 2021-09-16 17:27:02
+ * @LastEditTime: 2021-09-29 13:51:55
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/app.tsx
@@ -17,12 +17,22 @@ import RightContent from '@/components/RightContent';
 // import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
 import { BookOutlined, LinkOutlined } from '@ant-design/icons';
 
+import {loginOut} from '@/utils';
 import logoIcon from '../public/logo.png';
 
 const isDev = process.env.NODE_ENV === 'development';
 
 const loginPath = '/user/login';
 
+let hospSign:any='';
+
+if(history){
+  hospSign = history.location.query?.hospSign;
+  if(!hospSign){
+    hospSign = localStorage.getItem('hospSign');
+  }
+}
+
 
 /** 获取用户信息比较慢的时候会展示一个 loading */
 export const initialStateConfig = {
@@ -47,7 +57,8 @@ export async function getInitialState(): Promise<{
       }
       throw Error;
     } catch (error) {
-      history.push(loginPath);
+     
+      history.push(`${loginPath}?hospSign=${hospSign}`);
     }
     return undefined;
   };
@@ -101,14 +112,14 @@ const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
 
 
 const responseInterceptors = async (response: Response, options: RequestOptionsInit) => {
-  console.log({response,options});
+  // console.log({response,options});
   const requestMethod = options.method;
   try {
     const {status} = response;
     if(status == 200){
         //网络请求成功
         const _response = await response.clone().json();
-        const { status: dataStatus,errorMessage,data} = _response;
+        const { status: dataStatus,errorCode,errorMessage,data} = _response;
         if(dataStatus == 200){
              //接口请求成功
              if(requestMethod=='POST'){
@@ -121,8 +132,15 @@ const responseInterceptors = async (response: Response, options: RequestOptionsI
               return data;
              }
              return true;
+        }else if(errorCode == 499){
+          Modal.confirm({
+            title: '抱歉,登录已过期请重新登录!',
+            onOk: () => {
+              loginOut();
+            }
+          });
         }else {
-             //接口请求不成功
+             //接口请求信息错误
              notification.error({
               message:errorMessage
              });
@@ -130,6 +148,9 @@ const responseInterceptors = async (response: Response, options: RequestOptionsI
         
     }else {
       //网络请求失败
+       notification.error({
+        message:'服务器错误!'
+       });
        throw Error;
     }
   }catch(error){
@@ -155,9 +176,6 @@ export const request: RequestConfig = {
 };
 
 
-
-
-
 // ProLayout 支持的api https://procomponents.ant.design/components/layout
 export const layout: RunTimeLayoutConfig = ({ initialState }) => {
   return {
@@ -172,7 +190,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
       const { location } = history;
       // 如果没有登录,重定向到 login
       if (!initialState?.currentUser && location.pathname !== loginPath) {
-        history.push(loginPath);
+        history.push(`${loginPath}?hospSign=${hospSign}`);
       }
     },
     links: isDev

+ 259 - 0
src/components/CAUpload/index.jsx

@@ -0,0 +1,259 @@
+
+
+
+import { ImportOutlined } from '@ant-design/icons';
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { Button, Upload, message, Modal, Divider, Menu, Dropdown } from 'antd';
+import {envConfig} from '@/env';
+// import Cookies from 'js-cookie';
+
+// 服务器地址
+
+const {host} = envConfig;
+const Host = host;
+
+
+
+
+class CAUpload extends Component {
+    constructor(props) {
+        super(props);
+        // 模板下载事件
+        this.jumpTo = this.jumpTo.bind(this);
+        // 表格导出事件
+        this.exportExcel = this.exportExcel.bind(this);
+        // 表格上传事件
+        this.uploadProps.onChange = this.uploadProps.onChange.bind(this);
+
+        this.customRequestCallback = props.customRequestCallback ? props.customRequestCallback.bind(this) : () => { };
+
+        this.timer = null;
+
+        this.file = null;
+        
+        this.templeteUrl='';
+
+        this.label='';
+    }
+    // 模板下载
+    jumpTo() {
+        const userData = localStorage.getItem('userData');
+        const { token } = JSON.parse(userData);
+        if(this.templeteUrl == '/costAccount/excel/getcurrentTemplate'){
+            //找后端
+            window.open(`${Host}${this.templeteUrl}`);
+        }else{
+            window.open(`${Host}${this.templeteUrl}?token=${token}`);
+        }
+    }
+    // 上传参数
+    uploadProps = {
+        // // 发到后台的文件参数名
+        // name: 'file',
+        // // 接受的文件类型
+        // accept: '.xls,.xlsx',
+        // // 上传的地址
+        // action: Host + this.props.url,
+        // // 是否展示上传的文件
+        // showUploadList:false,
+        // // 上传的参数
+        // data: {
+
+        //     // uid: Cookies.get('uid')
+        // },
+        // // 设置上传的请求头部,IE10 以上有效
+        // headers: {
+        //     // authorization: 'authorization-text',
+        //     'Content-Type':'multipart/form-data',
+        //     'token':this.props.token,
+        // },
+        // 上传文件前的钩子函数
+        showUploadList: false,
+        beforeUpload() {
+            message.loading('正在导入中...');
+            return true;
+        },
+        customRequest: ({
+            file, data, action, onSuccess
+        }) => {
+            console.log({ file, data, action, onSuccess });
+            const formData = new FormData();
+            formData.set('file', file);
+            this.file = file;
+            if (this.props.type != 'dialog') this.customRequestCallback(formData);
+
+        },
+        // 上传文件改变时的状态
+        onChange(info) {
+            // console.log({info});
+            if (info.file.status !== 'uploading') {
+                console.log(info.file, info.fileList);
+            }
+            if (info.file.status === 'done') {
+                if (info.file.response.code !== 200) {
+                    setTimeout(() => {
+                        message.destroy();
+                        message.error(info.file.response.message);
+                    });
+                } else {
+                    this.props.importSuccessCallback && this.props.importSuccessCallback();
+                    setTimeout(() => {
+                        message.destroy();
+                        message.success('导入成功');
+                    });
+                }
+            } else if (info.file.status === 'error') {
+                setTimeout(() => {
+                    message.destroy();
+                    message.error('导入失败');
+                });
+            }
+        },
+    }
+
+    // 导出Excel表格
+    async exportExcel() {
+        const userData = localStorage.getItem('userData');
+        const { token } = JSON.parse(userData);
+        const url = Host + this.props.url + `/export?token=${token}`;
+        window.open(url);
+        //获取  全院其他收支设置列表
+    }
+
+    renderMenu(){
+        return (
+            <Menu onClick={this.handleMenuClick.bind(this)}>
+                  {
+                         this.props.templateHrefs&&Array.isArray(this.props.templateHrefs)&&this.props.templateHrefs.map((item,index)=>{
+                            return (
+                                <Menu.Item key={item.value}>{item.label}</Menu.Item>
+                            )
+                     })
+                  }
+            </Menu>
+        ) 
+    }
+
+
+    handleMenuClick(e){
+        // console.log('菜单点击',e);
+        const {key} = e;
+        this.label = ''
+        this.templeteUrl = key;
+        this.jumpTo();
+    }
+
+    handleButtonClick(e){
+          
+         const { type,templateHrefs } = this.props;
+
+         if(type == 'normal'){
+            this.templeteUrl = templateHrefs;
+         }
+         if(this.templeteUrl == ''){
+            message.error('请选择下载模板!');
+            return;
+         }
+         this.jumpTo();
+    }
+
+    openModal() {
+        const uploadProps = this.uploadProps;
+        Modal.confirm({
+            title: <React.Fragment>
+                导入数据
+                <Divider plain></Divider>
+            </React.Fragment>,
+            icon: null,
+            width: 600,
+            okText: '确定',
+            cancelText: '取消',
+            onOk: () => {
+                return new Promise((resolve, reject) => {
+                    this.timer = setTimeout(() => {
+                        resolve(true);
+                        this.customRequestCallback(this.file)
+                    }, 1500)
+                }).then(res => {
+                    // console.log({res})
+                })
+                    .catch(err => console.log({ err }))
+
+            },
+            content: <React.Fragment >
+                {this.props.content}
+                <Divider plain></Divider>
+                <Upload style={{ marginLeft: 10 }} key='importExcel' {...uploadProps} >
+                    <Button icon={<ImportOutlined />} type="primary">选择上传文件</Button>
+                </Upload>
+            </React.Fragment>
+        });
+    }
+
+    componentWillUnmount() {
+        clearTimeout(this.timer);
+    }
+
+    render() {
+        const uploadProps = this.uploadProps;
+        const { type } = this.props;
+        // console.log({...this.props});
+        if (type == 'normal'||!type) {
+            return [
+                // <Button style={{marginLeft: 10}} key='exportExcel' onClick={this.exportExcel}>导出</Button>,
+                <Upload style={{ marginLeft: 10 }} key='importExcel' {...uploadProps} >
+                    <Button type="primary">导入</Button>
+                </Upload>,
+                <Button style={{ marginLeft: 10 }} key='templateDowload' onClick={this.handleButtonClick.bind(this)}>模板下载</Button>
+            ]
+        }
+        if (type == 'dialog') {
+            return [
+                <Button type="primary" key='a' onClick={() => this.openModal()}>导入</Button>,
+                // <Button style={{marginLeft: 10}} key='templateDowloadTwo' onClick={this.jumpTo}>模板下载</Button>,
+                <Dropdown.Button  key='b' onClick={this.handleButtonClick.bind(this)} overlay={this.renderMenu()}>
+                    模板下载
+                </Dropdown.Button>
+
+            ]
+        }
+
+        return <></>
+
+    }
+}
+
+// 定义参数类型
+CAUpload.propTypes = {
+    // 模板下载地址
+    templateHrefs: PropTypes.oneOfType([
+        PropTypes.array,
+        PropTypes.string,
+    ]),    
+    // 上传地址
+    url: PropTypes.string.isRequired,
+    // 导入成功后的回调
+    importSuccessCallback: PropTypes.func,
+   
+    customRequestCallback: PropTypes.func,
+    //上传功能类型 【‘normal’,'dialog'】
+    type: PropTypes.string,
+    //渲染节点
+    content: PropTypes.node,
+};
+
+
+
+
+
+// const CAUpload = (props)=>{
+
+//     return (
+//         <Upload {...props}>
+//             <Button type="primary" icon={<ImportOutlined />}>导入</Button>
+//         </Upload>
+//     )
+// }
+
+export default CAUpload;

+ 79 - 27
src/components/MccsClickableTabs/index.less

@@ -1,33 +1,85 @@
+.wrap {
+  display: flex;
+  width: 100%;
+  flex-direction: row;
+  justify-content:flex-start;
+  flex-wrap: wrap;
+  align-items: center;
 
+  .tab {
+    width: 20%;
+    height: 28px;
+    cursor: pointer;
+    text-align: center;
+    line-height: 28px;
+    background: #F7F8FA;
+    border-radius: 14px;
+    font-size: 14px;
+    font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+    font-weight: 400;
+    color: #525866;
+    margin-right:16px;
+    margin-bottom: 16px;
 
+    &.on {
+      color: #3377FF;
+      background: #EBF1FF;
+    }
 
-.wrap {
-    display: flex;
-    width: 100%;
-    flex-direction: row;
-    justify-content:space-around;
-    flex-wrap: wrap;
-    align-items: center;
-    .tab {
-        width:30%;
-        height: 28px;
-        cursor: pointer;
-        text-align: center;
-        line-height: 28px;
-        background: #F7F8FA;
-        border-radius: 14px;
-        font-size: 14px;
-        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
-        font-weight: 400;
-        color: #525866;
-        // margin-right:16px;
-        margin-bottom: 16px;
+    &.disabled {
+        cursor: text;
+        background: #d9d9d9;
+    }
 
-        &.on {
-            color: #3377FF;
-            background: #EBF1FF;
-        }
 
+  }
+  &.mutiwrap {
+    flex-direction: column;
+    .muti {
+        display: flex;
+        flex-grow: 1;
+        width: 100%;
+        flex-direction: row;
+        justify-content: flex-start;
+        align-items: center;
+        margin-bottom: 16px;
+        .label {
+          text-align: center;
+          width: 10%;
+          font-size: 14px;
+          font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+          font-weight: 400;
+          color: #525866;
+        }
+        .valueWrap {
+            display: flex;
+            width: 90%;
+            flex-direction: row;
+            justify-content:flex-start;
+            align-items: center;
+            .tab {
+                width: 20%;
+                height: 28px;
+                cursor: pointer;
+                text-align: center;
+                line-height: 28px;
+                background: #F7F8FA;
+                border-radius: 14px;
+                font-size: 14px;
+                font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+                font-weight: 400;
+                color: #525866;
+                margin: 0 2%;
+                margin-bottom: 0;
+                // margin-right:16px;
+          
+                &.on {
+                  color: #3377FF;
+                  background: #EBF1FF;
+                }
+              }
+        }
         
-    }
-}
+      }
+  }
+}

+ 74 - 19
src/components/MccsClickableTabs/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 18:38:41
- * @LastEditTime: 2021-09-16 14:39:10
+ * @LastEditTime: 2021-09-29 17:28:49
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsClickableTabs/index.tsx
@@ -9,39 +9,94 @@
 
 
 
+import { Button } from 'antd';
 import React,{useState,useEffect} from 'react'
 
 import './index.less';
 
 const MccsClickableTabs:React.FC<MccsClickableTabs.propsType> = (props)=>{
+
     const [list,setList] = useState<MccsClickableTabs.TabType[]>([]);
-    const {tabClickHandle,defaultTabValue=-1,onChange} = props;
-    const [activedTab,setActivedTab] = useState(defaultTabValue);
+    const {tabClickHandle,clear,onChange,type='single',disabled=false} = props;
+    const [activedTab,setActivedTab] = useState<{label:string,value:any}>();
+
+
+    const clickHandle = (item:MccsClickableTabs.TabType,supItem:{label:string,value:string|number})=>{
 
-    const clickHandle = (item:MccsClickableTabs.TabType)=>{
-        tabClickHandle&&tabClickHandle(item);
-        onChange?.(item);  //Form传递过来的onChange,设置表单值
-        setActivedTab(item.value);
+        if(!disabled){
+            // console.log(item,type);
+            if(type=='single'){
+                tabClickHandle&&tabClickHandle(item);
+                onChange?.({label:`${item.value}`,value:item.value});  //Form传递过来的onChange,设置表单值
+                setActivedTab(supItem);
+            }
+            if(type=='multi'){
+                tabClickHandle&&tabClickHandle(supItem?supItem:null);
+                onChange?.({label:`${item.label}`,value:supItem});  //Form传递过来的onChange,设置表单值
+                setActivedTab({label:item.label,value:supItem});
+            }
+        }
     }
 
     useEffect(()=>{
-        const {data=[]} = props;
+        // console.log('tabProps',props);
+        const {data=[],value,clear} = props;
         setList(data);
+        // console.log({props});
+        if(value){
+            setActivedTab(value);
+        }else{
+            setActivedTab(type=='multi'?{label:'',value:{label:'',value:''}}:{label:'',value:''});
+        }
+        if(clear){
+            setActivedTab(type=='multi'?{label:'',value:{label:'',value:''}}:{label:'',value:''});
+        }
+        
     },[props]);
 
-    // useEffect(()=>{
-    //     console.log({props});
-    // },[]);
+
+
 
     return (
-        <div className='wrap'>
-                {
-                   list.map((item,index)=>{
-                        return (
-                            <div className={activedTab==item.value?'tab on':'tab'} key={index} onClick={()=>clickHandle(item)}>{item.label}</div>
-                        )
-                   })
-                }
+        <div className={type=='multi'?'mutiwrap wrap':'wrap'}>
+            {
+                type=='single'&&(
+                    <>
+                        {
+                        list.map((item,index)=>{
+                                return (
+                                    <div className={activedTab?.value==item.value?(disabled?'tab on disabled':'tab on'):disabled?'disabled tab':'tab'} key={index} onClick={()=>clickHandle(item,{label:'null',value:'null'})}>{item.label}</div>
+                                )
+                        })
+                        }
+                    </>    
+                )
+            }
+            {
+                type=='multi'&&(
+                    <>
+                        {
+                        list.map((item,index)=>{
+                                return (
+                                    <div className='muti' key={index}>
+                                        <div className='label'>{item.label}</div>
+                                        <div className='valueWrap'>
+                                              {
+                                                 item.list&&item.list.map((val,i)=>{
+                                                        return (
+                                                            <div className={activedTab?.label==item.label&&activedTab.value.value==val.value?'tab on':'tab'} key={i} onClick={()=>clickHandle(item,val)}>{val.label}</div>
+                                                        )
+                                                 }) 
+                                              }
+                                        </div>
+                                    </div>
+                                )
+                        })
+                        }
+                    </>    
+                )
+            }
+            
         </div>
     )
 }

+ 10 - 5
src/components/MccsClickableTabs/typings.d.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 18:39:49
- * @LastEditTime: 2021-09-16 14:36:05
+ * @LastEditTime: 2021-09-29 17:23:14
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsClickableTabs/typings.d.ts
@@ -11,13 +11,18 @@
 declare namespace MccsClickableTabs {
       type propsType = {
         data:TabType[],
-        defaultTabValue?:number|string,
-        onChange?:(value:TabType)=>void,
-        tabClickHandle?:(data:TabType)=>{}
+        defaultTabValue?:any[],
+        onChange?:({label:string,value:any})=>void,
+        tabClickHandle?:(data:TabType|null)=>{},
+        type?:'single'|'multi',
+        value?:{label:string,value:any},
+        disabled?:boolean,//是否禁用
+        clear?:boolean, //清空选中数据
       }
 
       type TabType = {
           label:string,
-          value:string|number
+          value:string|number,
+          list?:TabType[]
       }
 }

+ 11 - 3
src/components/MccsDrawerForm/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 16:25:53
- * @LastEditTime: 2021-09-16 14:20:12
+ * @LastEditTime: 2021-09-29 11:08:51
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsDrawerForm/index.tsx
@@ -10,14 +10,16 @@
 
 
 import React,{} from 'react'
+import { Drawer, Button } from 'antd';
 import {
     DrawerForm,
   } from '@ant-design/pro-form';
 
 const MccsDrawerForm:React.FC<MccsDrawerForm.propsType> = (props)=>{
-    const {children,...rest} = props;
-    return (
+    const {children,noFormMode,onVisibleChange,...rest} = props;
+    return !noFormMode?(
         <DrawerForm
+             onVisibleChange={onVisibleChange}
              drawerProps={{
                  
                 destroyOnClose:true
@@ -26,6 +28,12 @@ const MccsDrawerForm:React.FC<MccsDrawerForm.propsType> = (props)=>{
         >
             {children}
         </DrawerForm>
+    ):(
+        <Drawer 
+           {...rest}
+        >
+            {children}
+        </Drawer>
     )
 }
 

+ 2 - 1
src/components/MccsDrawerForm/typings.d.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 16:26:10
- * @LastEditTime: 2021-09-15 16:32:02
+ * @LastEditTime: 2021-09-29 11:05:08
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsDrawerForm/typings.d.ts
@@ -10,6 +10,7 @@
 
 declare namespace MccsDrawerForm {
      type propsType = {
+          noFormMode?:boolean,  //是否不带有表单
           [propsName:string]:any
      }
 }

+ 63 - 0
src/components/MccsEditableTable/index.tsx

@@ -0,0 +1,63 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 10:45:50
+ * @LastEditTime: 2021-09-28 17:03:49
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/MccsEditableTable/index.tsx
+ */
+
+
+import React,{useState,useEffect,useRef} from 'react'
+import { EditableProTable } from '@ant-design/pro-table';
+
+
+
+const MccsEditableTable: React.FC<MccsEditableTableType.MccsEditableTableProps> = (props) => {
+
+    const {columns=[],request,addHandle,editHandle,reload,...rest} = props;
+    const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
+    const [dataSource,setDataSource] = useState<any>([]);
+    const tableRef = useRef<any>();
+
+    useEffect(() => {
+        
+        tableRef.current.reload();
+    
+    }, [reload]);
+
+ 
+
+    return (
+        <EditableProTable
+            {...rest}
+            rowKey="id"
+            columns={columns}
+            request={request}
+            value={dataSource}
+            actionRef={tableRef}
+            onChange={setDataSource}
+            recordCreatorProps={
+               {
+                  record: () => ({ id:'-'}),
+               }
+            }
+            editable={{
+                type: 'multiple',
+                editableKeys,
+                onSave: async (rowKey, data, row) => {
+                  const {id} = data;
+                  if(id=='-'){
+                       //新增
+                       addHandle&&addHandle(data);
+                  }else{
+                       editHandle&&editHandle(data);
+                  }
+                },
+                onChange: setEditableRowKeys,
+              }}
+        />
+    )
+}
+
+export default MccsEditableTable

+ 28 - 0
src/components/MccsEditableTable/typings.d.ts

@@ -0,0 +1,28 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 10:46:48
+ * @LastEditTime: 2021-09-27 17:56:12
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/MccsEditableTable/typings.d.ts
+ */
+
+
+
+
+
+declare namespace MccsEditableTableType {
+
+    type RowDataType = {
+        [key:string]:any
+    }
+     
+    type MccsEditableTableProps = {
+         columns:any[],
+         request?:Promise,
+         addHandle?:(data:any)=>void,
+         editHandle?:(data:any)=>void,
+         reload?:boolean,
+         [key:string]:any
+    }
+}

+ 88 - 81
src/components/MccsFileTree/index.tsx

@@ -1,15 +1,15 @@
 /*
  * @Author: your name
  * @Date: 2021-09-06 10:28:12
- * @LastEditTime: 2021-09-14 16:36:03
+ * @LastEditTime: 2021-09-26 16:13:56
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsFileTree/index.tsx
  */
 
 
-import React, { ReactNode, useEffect, useState,MouseEvent} from 'react'
-import { Input, Spin,Image } from 'antd';
+import React, { ReactNode, useEffect, useState, MouseEvent } from 'react'
+import { Input, Spin, Image, Popconfirm } from 'antd';
 import { PlusOutlined } from '@ant-design/icons';
 import DirectoryTree from './components/DirectoryTree';
 import './index.less'
@@ -22,93 +22,100 @@ const { Search } = Input;
 
 
 
-enum Types {'add','del','edit','search'};
+enum Types { 'add', 'del', 'edit', 'search' };
 
 type TypeVals = keyof typeof Types;
 
 type MccsFileTreeProps = {
-  onSelectHandle?: (data:MccsFileTree.childTree) => void, //选中回调
-  actionHandle?:({type,data}:{type:string,data:MccsFileTree.childTree}) => void, //操作回调,包括编辑/删除/新增/搜索
-  searchHandle?:(val:any)=>void,  
+  onSelectHandle?: (data: MccsFileTree.childTree) => void, //选中回调
+  actionHandle?: ({ type, data }: { type: string, data: MccsFileTree.childTree }) => void, //操作回调,包括编辑/删除/新增/搜索
+  searchHandle?: (val: any) => void,
   switcherIcon?: ReactNode,
-  treeData: MccsFileTree.childTree[]|[],
-  defaultSelected?:string,  //传id
-  formContent?:ReactNode,
-  editable?:boolean
+  treeData: MccsFileTree.childTree[] | [],
+  defaultSelected?: string,  //传id
+  formContent?: ReactNode,
+  editable?: boolean
 }
 
-  const MccsFileTree: React.FC<MccsFileTreeProps> = (props) => {
-  const {treeData,onSelectHandle,actionHandle,defaultSelected,searchHandle,editable} = props;
+const MccsFileTree: React.FC<MccsFileTreeProps> = (props) => {
+  const { treeData, onSelectHandle, actionHandle, defaultSelected, searchHandle, editable } = props;
   const [isLoading, setIsLoading] = useState(true);
   //当前选中的
-  const [currentActivedIndex, setcurrentActivedIndex] = useState(defaultSelected?defaultSelected:'');
+  const [currentActivedIndex, setcurrentActivedIndex] = useState(defaultSelected ? defaultSelected : '');
 
-  const actionFunc = (event:MouseEvent,type:TypeVals,data:MccsFileTree.childTree)=>{
-       event?.stopPropagation();
-       actionHandle&&actionHandle({type,data:data});
+  const actionFunc = (event:MouseEvent|undefined, type: TypeVals, data: MccsFileTree.childTree) => {
+    event?.stopPropagation();
+    actionHandle && actionHandle({ type, data: data });
   }
 
   //操作
-  const Action =(props:MccsFileTree.childTree)=>{
-       const {isLeaf} = props;
-       return (
-        <div className='action'>
-              {
-                !isLeaf&&(  //非叶子结点才可以新增
-                  <>
-                  <Image width={15} preview={false} onClick={(e)=>actionFunc(e,'add',props)} src={'https://i.postimg.cc/13HdKg0T/image.png'} />
-                  <div style={{width:5}}></div>
-                  </>
-                )
-              }
-              <Image width={15} preview={false} onClick={(e)=>actionFunc(e,'edit',props)} src={'https://i.postimg.cc/13HdKg0T/image.png'} />
-              <div style={{width:5}}></div>
-              <Image width={15} preview={false} onClick={(e)=>actionFunc(e,'del',props)} src={'https://i.postimg.cc/HLkhvpBL/image.png'} />
-        </div>
-       )
+  const Action = (props: MccsFileTree.childTree) => {
+    const { isLeaf } = props;
+    return (
+      <div className='action'>
+        {
+          !isLeaf && (  //非叶子结点才可以新增
+            <>
+              <Image width={15} preview={false} onClick={(e) => actionFunc(e, 'add', props)} src={'https://i.postimg.cc/fb3Fq26H/add.png'} />
+              <div style={{ width: 5 }}></div>
+            </>
+          )
+        }
+        <Image width={15} preview={false} onClick={(e) => actionFunc(e, 'edit', props)} src={'https://i.postimg.cc/13HdKg0T/image.png'} />
+        <div style={{ width: 5 }}></div>
+        <Popconfirm
+          title="是否确定删除?"
+          onConfirm={(e)=>{actionFunc(e, 'del', props)}}
+          okText="确定"
+          cancelText="取消"
+        >
+          <Image width={15} preview={false} onClick={e=>e.stopPropagation()}  src={'https://i.postimg.cc/HLkhvpBL/image.png'} />
+        </Popconfirm>
+      </div>
+    )
   }
 
   //叶子结点结构
-  const TreeNode = (nodeProps:MccsFileTree.childTree)=>{
-       const {title,id} = nodeProps;
-       return (
-            <div className={currentActivedIndex==id?'treeNode actived':'treeNode'} onClick={onSelectHandle?()=>{
-              setcurrentActivedIndex(id);
-              onSelectHandle(nodeProps)
-            }:()=>{setcurrentActivedIndex(id);}}>
-              <div  style={{display:'flex',marginRight:5,justifyContent:'center',alignItems:'center'}} ><Image width={15} preview={false} src={'https://i.postimg.cc/vHvhJJ1x/image.png'} /> </div>
-                  <div className='treeNodeInner'>{title}</div>
-                  
-                  {(currentActivedIndex==id&&editable)&&<Action {...nodeProps} />  /*点击展示操作项*/}
-              </div>
-       )
+  const TreeNode = (nodeProps: MccsFileTree.childTree) => {
+    const { title, id,code } = nodeProps;
+    return (
+      <div className={currentActivedIndex == id ? 'treeNode actived' : 'treeNode'} onClick={onSelectHandle ? () => {
+        setcurrentActivedIndex(id);
+        onSelectHandle(nodeProps)
+      } : () => { setcurrentActivedIndex(id); }}>
+        <div style={{ display: 'flex', marginRight: 5, justifyContent: 'center', alignItems: 'center' }} ><Image width={15} preview={false} src={'https://i.postimg.cc/vHvhJJ1x/image.png'} /> </div>
+        <div className='treeNodeInner'>{`${code} ${title}`}</div>
+
+        {(currentActivedIndex == id && editable) && <Action {...nodeProps} />  /*点击展示操作项*/}
+      </div>
+    )
   }
   //递归树形结构
-  const loop = (data:MccsFileTree.childTree,i:number) => {
-     
-       const {title,children=[],...restProps} = data;
-
-       const label = <div className="node">{title}</div>;
-
-       if(data.isLeaf){
-           return <TreeNode key={data.id} currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex}  title={title} {...restProps} />
-       }
-       return (
-        <DirectoryTree key={data.id} currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex} 
-          nodeLabel={label}  {...data}  onClick={()=>onSelectHandle?onSelectHandle(data):()=>{}}
-          action={editable&&<Action  {...data}/>}  defaultCollapsed={true}
-        >
-               {
-                 children.map((item,index)=>{
-                      if(item.isLeaf){
-                          return <TreeNode currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex}  key={index}   {...item} />
-                      }else{
-                         return loop(item,index);
-                      }
-                 })
-               }
-        </DirectoryTree>
-       )
+  const loop = (data: MccsFileTree.childTree, i: number) => {
+
+    const { title, children = [], ...restProps } = data;
+
+    const label = <div className="node">{`${restProps.code} ${title}`}</div>;
+
+    if (data.isLeaf) {
+      return <TreeNode key={data.id} currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex} title={title} {...restProps} />
+    }
+    return (
+      <DirectoryTree key={data.id} currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex}
+        nodeLabel={label}  {...data} onClick={() => onSelectHandle ? onSelectHandle(data) : () => { }}
+        action={editable && <Action  {...data} />} defaultCollapsed={true}
+      >
+        {
+          children.map((item, index) => {
+            if (item.isLeaf) {
+              return <TreeNode currentActivedIndex={currentActivedIndex} setcurrentActivedIndex={setcurrentActivedIndex} key={index}   {...item} />
+            } else {
+              return loop(item, index);
+            }
+          })
+        }
+      </DirectoryTree>
+    )
   }
 
   useEffect(() => {
@@ -121,24 +128,24 @@ type MccsFileTreeProps = {
     <React.Fragment>
       <div className="searchBar">
         {
-          editable&&(
-            <div className="add" onClick={e=>actionFunc(e,'add',{
-              title:'',
-              id:`0`,
-              isLeaf:false,
-              code:`${new Date().getTime()}`,
-              children:[]
+          editable && (
+            <div className="add" onClick={e => actionFunc(e, 'add', {
+              title: '',
+              id: `0`,
+              isLeaf: false,
+              code: `${new Date().getTime()}`,
+              children: []
             })}><PlusOutlined /></div>
           )
         }
-        <Search placeholder='请输入' className="inputArea" allowClear onSearch={(val,e)=>searchHandle&&searchHandle(val)} />
+        <Search placeholder='请输入' className="inputArea" allowClear onSearch={(val, e) => searchHandle && searchHandle(val)} />
       </div>
 
       {
         isLoading ? <div className='spinWrap'><Spin delay={500} /></div> : (
           <>
             {treeData.map((node, i) => {
-              return loop(node,i);
+              return loop(node, i);
             })}
           </>
         )

+ 6 - 5
src/components/MccsModal/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-08 17:09:34
- * @LastEditTime: 2021-09-10 16:51:34
+ * @LastEditTime: 2021-09-27 18:37:12
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsModal/index.tsx
@@ -19,7 +19,7 @@
 
 
 
-import React,{useRef,createContext} from 'react'
+import React,{useRef,createContext,useEffect,useState} from 'react'
 import {
     ModalForm,
   } from '@ant-design/pro-form';
@@ -32,7 +32,7 @@ import {
 
 type MccsModalProps = {
     title:string,
-    visible:boolean,
+    visible?:boolean,
     [propName: string]: any;
 }
 
@@ -44,14 +44,15 @@ const MccsModalContext: React.Context<MccsModal.MccsModalContextT> = createConte
 
 
 const MccsModal: React.FC<MccsModalProps> = (props) => {
-  const { title,visible,children,...restProps } = props;
+  const { title,visible=false,children,...restProps } = props;
   const formRef = useRef<ProFormInstance>();
-
+  // const [ifVisible, setIfVisible] = useState(false)
   return (
     <ModalForm
       title={title}
       visible={visible}
       formRef={formRef}
+      modalProps={{destroyOnClose:true}}
       {...restProps}
     >
       <MccsModalContext.Provider value={{formRef:formRef}}>

+ 29 - 21
src/components/MccsRecordList/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 09:17:28
- * @LastEditTime: 2021-09-16 15:17:37
+ * @LastEditTime: 2021-09-27 18:55:45
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsRecordList/index.tsx
@@ -18,7 +18,7 @@ import './index.less';
 
 const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
 
-    const { title, list = [], actionFunc} = props;
+    const { title, list = [], actionFunc, actionNode } = props;
     const [currentOpen, setCurrentOpen] = useState<[number, number] | []>([]);
     const [data, setData] = useState<MccsRecordList.MccsRecordListType>([]);
 
@@ -30,13 +30,10 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
         }
     }
 
-    const actionHandle = (supIndex: number,subIndex:number,lowerIndex:number) => {
-        let flag = actionFunc&&actionFunc();  //返回true表示服务器删除成功!
-        if(flag){
-            let _data = data;
-            _data[supIndex].details[subIndex].historyRecords.splice(lowerIndex,1);
-            setData([..._data]);
-        }
+    const actionHandle = (supIndex: number, subIndex: number, lowerIndex: number) => {
+        let _data = data;
+        actionFunc && actionFunc(_data[supIndex].details[subIndex].historyRecords[lowerIndex]);  //返回true表示服务器删除成功!
+
     }
 
 
@@ -44,6 +41,7 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
         if (list) {
             setData(list);
         }
+
         // setData([
         //     {
         //         evaluation: 'C',
@@ -121,10 +119,12 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
                                                             <div className='item' key={detailListIndex}>
                                                                 <div className='itemInner'>
                                                                     <div className='itemHeader'>
-                                                                        <span className='type'>{detailsList.recordTypeName}</span>
+                                                                        {
+                                                                            detailsList.recordTypeName&&<span className='type'>{detailsList.recordTypeName}</span>
+                                                                        }
                                                                         <div className='recordContent'>
                                                                             <span className='bolder'>{detailsList.name}</span>
-                                                                            上传了台帐
+                                                                            {detailsList.recordTypeName?'上传了台帐':'自评结果为'}
                                                                             <span className='bolder'>{detailsList.fileName}</span>
                                                                         </div>
                                                                     </div>
@@ -132,25 +132,33 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
                                                                         {
                                                                             detailsList.historyRecords.length > 0 && (
                                                                                 <>
-                                                                                <div className={(currentOpen[0] == index && currentOpen[1] == detailListIndex) ? 'history on' : 'history'} onClick={() => historyHandle(index, detailListIndex)}>历史记录</div>
-                                                                                <Divider type="vertical" />
+                                                                                    <div className={(currentOpen[0] == index && currentOpen[1] == detailListIndex) ? 'history on' : 'history'} onClick={() => historyHandle(index, detailListIndex)}>历史记录</div>
+                                                                                    <Divider type="vertical" />
                                                                                 </>
                                                                             )
                                                                         }
                                                                         <span className='date'>{detailsList.createTime}</span>
                                                                     </div>
-                                                                    <div className='action'>
-                                                                        <a href={detailsList.fileUrl}>下载文件</a>
-                                                                    </div>
+                                                                    {
+                                                                        actionNode && (
+                                                                            <div className='action'>
+                                                                                {
+                                                                                    actionNode(detailsList)
+                                                                                }
+
+                                                                            </div>
+                                                                        )
+                                                                    }
+
                                                                 </div>
                                                                 {
-                                                                    (currentOpen[0] == index && currentOpen[1] == detailListIndex&&detailsList.historyRecords.length > 0) && (
+                                                                    (currentOpen[0] == index && currentOpen[1] == detailListIndex && detailsList.historyRecords.length > 0) && (
                                                                         <div className='subListWrap'>
-            
+
                                                                             <Timeline pending={false}>
                                                                                 {
                                                                                     item.details[detailListIndex].historyRecords.map((val, i) => {
-                            
+
                                                                                         return (
                                                                                             <React.Fragment key={i}>
                                                                                                 {
@@ -160,7 +168,7 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
                                                                                                                 <div className='version'>{val.versionName}</div>
                                                                                                                 <div className='actionPeople'>{`上传人:${val.name}`}</div>
                                                                                                                 <div className='time'>{val.time}</div>
-                                                                                                                <span className='action' onClick={() => actionHandle(index,detailListIndex,i)}></span>
+                                                                                                                <span className='action' onClick={() => actionHandle(index, detailListIndex, i)}></span>
                                                                                                             </div>
                                                                                                         </Timeline.Item >
                                                                                                     )
@@ -172,7 +180,7 @@ const MccsRecordList: React.FC<MccsRecordList.propsType> = (props) => {
                                                                                                                 <div className='version'>{val.versionName}</div>
                                                                                                                 <div className='actionPeople'>{`上传人:${val.name}`}</div>
                                                                                                                 <div className='time'>{val.time}</div>
-                                                                                                                <span className='action' onClick={() => actionHandle(index,detailListIndex,i)}></span>
+                                                                                                                <span className='action' onClick={() => actionHandle(index, detailListIndex, i)}></span>
                                                                                                             </div>
                                                                                                         </Timeline.Item >
                                                                                                     )

+ 15 - 12
src/components/MccsRecordList/typings.d.ts

@@ -1,39 +1,42 @@
 /*
  * @Author: your name
  * @Date: 2021-09-15 09:17:43
- * @LastEditTime: 2021-09-15 15:58:59
+ * @LastEditTime: 2021-09-26 15:28:18
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsRecordList/typings.d.ts
  */
 
 
-
-
 declare namespace MccsRecordList {
 
       type propsType = {
         title:string,
         list?:MccsRecordListType|[],
-        actionFunc?:()=>boolean,
+        actionFunc?:(data:historyRecordsItem)=>void,  //删除历史版本回调
+        actionText?:string,
+        actionNode?:(item?:MccsRecordListItemInnerDetail)=>ReactNode,  //记录操作按钮
       }
 
       type historyRecordsItem = {
         versionName:string,
         name:string,
         time:string,
+        id:number
+      }
+      
+      type MccsRecordListItemInnerDetail = {
+        name:string,
+        fileName:string,
+        fileUrl:string,
+        createTime:string,
+        recordTypeName?:string,
+        historyRecords:historyRecordsItem[]|[]
       }
 
       type MccsRecordListItem = {
           evaluation:string,
-          details:{
-            name:string,
-            fileName:string,
-            fileUrl:string,
-            createTime:string,
-            recordTypeName:string,
-            historyRecords:historyRecordsItem[]|[]
-          }[]
+          details:MccsRecordListItemInnerDetail[]
       }
 
       type MccsRecordListType = MccsRecordListItem[]

+ 2 - 2
src/components/MccsTable/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 11:14:06
- * @LastEditTime: 2021-09-16 10:36:19
+ * @LastEditTime: 2021-09-24 11:31:12
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/components/MccsTable/index.tsx
@@ -28,7 +28,7 @@ const MccsTable=React.forwardRef<MccsTable.MccsTableRef,MccsTable.MccsTable>((pr
          return colums.map((item,index)=>{
                 return {
                      ...item,
-                     ellipsis:true
+                    //  ellipsis:true
                 }
          })
     }

+ 8 - 0
src/components/MccsUpload/README.md

@@ -0,0 +1,8 @@
+<!--
+ * @Author: your name
+ * @Date: 2021-09-17 18:19:20
+ * @LastEditTime: 2021-09-17 18:19:21
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/MccsUpload/README.md
+-->

+ 0 - 0
src/components/MccsUpload/index.less


+ 42 - 0
src/components/MccsUpload/index.tsx

@@ -0,0 +1,42 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-17 18:18:58
+ * @LastEditTime: 2021-09-18 15:34:40
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/MccsUpload/index.tsx
+ */
+
+
+import React from 'react'
+import { Upload, message, Button } from 'antd';
+import { UploadOutlined } from '@ant-design/icons';
+
+const MccsUpload:React.FC<MccsUpload.propsType> = (props)=>{
+    
+    const {children,value:fileList,...rest} = props;
+
+    const config = {
+        // onChange :(info:any)=>{
+        //     console.log({info});
+            
+        // },
+        // onRemove:(file:any)=>{
+        //     console.log({file});
+        // }
+    }
+
+
+
+    return (
+        <Upload  defaultFileList={fileList} {...config}  {...rest}>
+              {
+                  children?children:(
+                    <Button icon={<UploadOutlined />}>上传文件</Button>
+                  )
+              }
+        </Upload>
+    )
+}
+
+export default MccsUpload

+ 20 - 0
src/components/MccsUpload/typings.d.ts

@@ -0,0 +1,20 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-17 18:19:13
+ * @LastEditTime: 2021-09-17 20:09:57
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/MccsUpload/typings.d.ts
+ */
+
+
+
+
+declare namespace MccsUpload {
+
+     type propsType = {
+       
+         value?:any,
+         [key:string]:any
+     }
+}

+ 15 - 22
src/components/RightContent/AvatarDropdown.tsx

@@ -1,38 +1,31 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-03 14:28:27
+ * @LastEditTime: 2021-09-29 18:32:49
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/components/RightContent/AvatarDropdown.tsx
+ */
 import React, { useCallback } from 'react';
 import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
 import { Avatar, Menu, Spin } from 'antd';
 import { history, useModel } from 'umi';
-import { stringify } from 'querystring';
+
 import HeaderDropdown from '../HeaderDropdown';
 import styles from './index.less';
-import { outLogin } from '@/services/ant-design-pro/api';
+// import { outLogin } from '@/services/ant-design-pro/api';
 import type { MenuInfo } from 'rc-menu/lib/interface';
 
+import {loginOut} from '@/utils';
+
 export type GlobalHeaderRightProps = {
   menu?: boolean;
 };
 
-/**
- * 退出登录,并且将当前的 url 保存
- */
-const loginOut = async () => {
-  await outLogin();
-  const { query = {}, pathname } = history.location;
-  const { redirect } = query;
-  // Note: There may be security issues, please note
-  if (window.location.pathname !== '/user/login' && !redirect) {
-    history.replace({
-      pathname: '/user/login',
-      search: stringify({
-        redirect: pathname,
-      }),
-    });
-  }
-};
+
 
 const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
   const { initialState, setInitialState } = useModel('@@initialState');
-
   const onMenuClick = useCallback(
     (event: MenuInfo) => {
       const { key } = event;
@@ -71,12 +64,12 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
 
   const menuHeaderDropdown = (
     <Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
-      {menu && (
+      {/* {menu && (
         <Menu.Item key="center">
           <UserOutlined />
           个人中心
         </Menu.Item>
-      )}
+      )} */}
       {menu && (
         <Menu.Item key="settings">
           <SettingOutlined />

+ 13 - 0
src/env.ts

@@ -0,0 +1,13 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-26 18:13:39
+ * @LastEditTime: 2021-09-26 18:15:21
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/env.ts
+ */
+
+
+export const envConfig = {
+    host:process.env.NODE_ENV == 'development'?'http://112.124.59.133:8083':'http://112.124.59.133:8083'
+}

+ 19 - 1
src/global.less

@@ -14,7 +14,7 @@ body,
 
 .ant-pro-sider-logo {
    h1 {
-    font-size: 16px;
+    font-size:1rem;
    }
 }
 .ant-menu-submenu-selected {
@@ -29,6 +29,24 @@ body,
   border-color: #00528E;
 }
 
+.ant-tabs-top > .ant-tabs-nav::before {
+   border: none;
+}
+
+.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn {
+  color: #00528E;
+  font-size: 16px;
+  font-weight: bold;
+  font-family: 'SourceHanSansCN-Bold, SourceHanSansCN';
+  text-shadow: 0 0 0.25px currentColor;
+}
+
+.ant-tabs-large > .ant-tabs-nav .ant-tabs-tab {
+  padding: 16px 0;
+  font-size: 16px;
+  padding-bottom:10px;
+}
+
 
 //---------------custom------------
 

+ 4 - 4
src/global.tsx

@@ -1,8 +1,8 @@
 /*
  * @Author: your name
  * @Date: 2021-09-03 14:28:27
- * @LastEditTime: 2021-09-03 16:22:34
- * @LastEditors: your name
+ * @LastEditTime: 2021-09-22 10:30:10
+ * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/global.tsx
  */
@@ -43,7 +43,7 @@ if (pwa) {
         worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
       });
       // Refresh current page to use the updated HTML and other assets after SW has skiped waiting
-      window.location.reload(true);
+      window.location.reload();
       return true;
     };
     const key = `open${Date.now()}`;
@@ -81,7 +81,7 @@ if (pwa) {
   });
 
   // remove all caches
-  if (window.caches && window.caches.keys()) {
+  if (window.caches && await window.caches.keys()) {
     caches.keys().then((keys) => {
       keys.forEach((key) => {
         caches.delete(key);

+ 9 - 4
src/models/allModels.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-06 17:38:49
- * @LastEditTime: 2021-09-14 10:49:38
+ * @LastEditTime: 2021-09-23 09:06:27
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/models/allModels.ts
@@ -9,9 +9,11 @@
 import { useState, useCallback } from 'react'
 import accreditationDetail from '@/pages/GradeHospitalAccreditation/accreditationDetail/model';
 import articleManagement from '@/pages/GradeHospitalAccreditation/articleManagement/model';
+import ledgerUpload from '@/pages/GradeHospitalAccreditation/ledgerUpload/model';
+import publicData from '@/pages/DataManagement/publicData/model';
 
 export default function allModel() {
-  const [user, setUser] = useState(null)
+  const [user, setUser] = useState<string>()
 
   const signin = useCallback((account, password) => {
     // signin implementation
@@ -25,9 +27,12 @@ export default function allModel() {
 
   return {
     user,
+    setUser,
     signin,
     signout,
-    accreditationDetail, //评审细则
-    articleManagement,//条文管理
+    accreditationDetail:{...accreditationDetail()}, //评审细则
+    articleManagement:{...articleManagement()},//条文管理
+    ledgerUpload:{...ledgerUpload()}, //台账上传
+    publicData:{...publicData()},//公共资料
   }
 }

+ 6 - 0
src/pages/DataManagement/publicData/index.less

@@ -0,0 +1,6 @@
+
+
+
+.ant-form-vertical .ant-form-item-label {
+    display: none !important;
+}

+ 470 - 0
src/pages/DataManagement/publicData/index.tsx

@@ -0,0 +1,470 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-23 08:49:14
+ * @LastEditTime: 2021-09-29 18:50:05
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/DataManagement/publicData/index.tsx
+ */
+
+
+import React, { useRef, useEffect, useState } from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+import MccsProCard from '@/components/MccsProCard/index';
+import MccsFileTree from '@/components/MccsFileTree/index';
+import MccsTable from '@/components/MccsTable/index';
+import MccsDrawerForm from '@/components/MccsDrawerForm/index';
+import { MccsModal } from '@/components/MccsModal';
+import MccsUpload from '@/components/MccsUpload';
+import { useModel } from 'umi';
+
+import './index.less'
+
+import { Form, Table, Space, Button, Popconfirm } from 'antd'
+
+
+import {
+    ProFormText,
+    ProFormSelect,
+    ProFormDateRangePicker,
+} from '@ant-design/pro-form';
+import { values } from '@umijs/deps/compiled/lodash';
+
+
+
+type PublicDataType = {
+
+}
+
+type SelectedRowsType = {
+    [propsName: string]: any
+}
+
+const PublicData: React.FC<PublicDataType> = (props) => {
+
+    const columns = [
+
+        {
+            key: 'keyword',
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                    <Form.Item name='keyword'>
+                        <ProFormText placeholder='资料名称、条文条款' />
+                    </Form.Item>
+                )
+            },
+        },
+        {
+            key: 'date',
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                    <ProFormDateRangePicker fieldProps={{ format: 'yyyy-MM-DD' }} placeholder={['开始时间', '结束时间']} />
+                )
+            },
+        },
+        {
+            title: 'ID',
+            key: 'id',
+            dataIndex: 'id',
+            hideInSearch: true,
+
+        },
+        {
+            title: '文件名称',
+            dataIndex: 'fileName',
+            hideInSearch: true,
+            width: '35%'
+        },
+        {
+            title: '添加时间',
+            dataIndex: 'createDateTime',
+            hideInSearch: true,
+        },
+        {
+            title: '关联条款',
+            hideInSearch: true,
+            dataIndex: 'articles',
+            render: (_: any, record: any) => {
+                //    console.log({record});
+                const { articlesList = [] } = record;
+                return (articlesList.map((t: any) => t.numStr)).join(',');
+            }
+        },
+        {
+            title: '操作',
+            width: '20%',
+            valueType: 'option',
+            render: (_: any, record: any) => {
+                // console.log({record});
+                const { ruleStatus, fileUrl } = record;
+                const arr = [
+                    <a key="1" href={fileUrl} >预览</a>,
+                    <Popconfirm
+                        title="是否确定删除?"
+                        onConfirm={()=>delFileHandle(record)}
+                        onCancel={()=>{}}
+                        okText="确定"
+                        cancelText="取消"
+                    >
+                        <a key="2" >删除</a>
+                    </Popconfirm>
+                ]
+                // 1 展示 0掩藏
+                return ruleStatus == 0 ? [...arr] : [<a key="3"
+                    onClick={() => {
+                        setSelectedFiles([record]);
+                        connectHandle(record)
+                    }}>关联条款</a>, ...arr]
+            },
+        },
+    ];
+
+    const drawerTableColumns = [
+        {
+            key: 'keyword',
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                    <Form.Item name='keyword'>
+                        <ProFormText placeholder='四码/条款' />
+                    </Form.Item>
+                )
+            },
+        },
+        {
+            title: 'ID',
+            key: 'id',
+            dataIndex: 'id',
+            hideInTable: true,
+            hideInSearch: true,
+        },
+        {
+            title: '四码',
+            key: 'numStr',
+            dataIndex: 'numStr',
+            hideInSearch: true,
+            width: '30%'
+        },
+        {
+            title: '四码细则名',
+            key: 'name',
+            dataIndex: 'name',
+            hideInSearch: true,
+            width: '70%',
+            ellipsis: true
+        },
+    ]
+
+    const tableRef = useRef<MccsTable.MccsTableRef>();
+
+    const [actionType, setActionType] = useState('add');
+
+    const [MccsModalVisible, setMccsModalVisible] = useState(false);
+
+    const [treeDataModelInit, setTreeDataModelInit] = useState<{ name: string, cateType: number }>();
+
+    const [drawerVisible, setDrawerVisible] = useState(false);
+
+    const [selectedRowIds, setSelectedRowIds] = useState<number[]>([]); //条文id
+
+    const [selectedFiles, setSelectedFiles] = useState<any[]>([]);  //文件id
+
+    const [uploadModalVisible, setUploadModalVisible] = useState(false);
+
+
+    const { publicData } = useModel('allModels', model => {
+        return { publicData: model.publicData };
+    });
+
+    //搜索回调
+    const searchHandle = (val: any) => {
+        publicData.getTreeData(val);
+    }
+
+    const onSelectHandle = (data: SelectedTreeDataType) => {
+        publicData.setCurrentActivedTree(data);
+        //重新获取数据
+        tableRef?.current?.getTableRef().current?.reload();
+    }
+
+    const MccsModalVisibleChangeHandle = (bool: boolean) => {
+        !bool && setTreeDataModelInit(undefined)
+        setMccsModalVisible(bool);
+    }
+
+    const connectHandle = (records?: any) => {
+        //关联条款 records传参解决useState异步拿不到数据
+        let defaultSelectedAccreditation: number[] = []; //默认选中的条文
+
+        if (!records) {
+            selectedFiles.map((item: any) => {
+                const { articlesList = [] } = item;
+                const arr = articlesList.map((t: any) => t.ruleId);
+                defaultSelectedAccreditation = defaultSelectedAccreditation.concat(arr);
+            });
+        } else {
+            const { articlesList = [] } = records;
+            defaultSelectedAccreditation = articlesList.map((t: any) => t.ruleId);
+        }
+
+        setSelectedRowIds(Array.from(new Set(defaultSelectedAccreditation)));
+        setDrawerVisible(true);
+    }
+
+    const delFileHandle = (records: any) => {
+        //删除树结构对应的公共资料
+        publicData.delTableFlieListFunc(records.id);
+    }
+
+
+    //操作回调
+    const actionHandle = ({ type, data }: { type: string, data: MccsFileTree.childTree }) => {
+
+        data ? publicData.setCurrentActived(data) : publicData.setCurrentActived(undefined);  //点击获取当前树数据
+
+        if (type == 'del') {
+            //删除
+            setActionType('del');
+            if (data) {
+                const { id } = data;
+                publicData.delTreeHandle([Number(id)]);
+            }
+
+        }
+        if (type == 'edit' && data) {
+            setActionType('edit');
+            setTreeDataModelInit({ name: data.title, cateType: data.cateType });
+            setMccsModalVisible(true);
+        }
+        if (type == 'add') {
+            setActionType('add');
+            setMccsModalVisible(true);
+        }
+    }
+
+    const MccsModalFinnishHandle = (values: { name: string, cateType: number }) => {
+        //   console.log({values});
+        let parentId = 0;  //默认最顶级为0
+        if (publicData.currentActived) {
+            parentId = Number(publicData.currentActived.id)
+        }
+        if (actionType == 'add') {
+            publicData.addTreeHandle({ ...values, parentId });
+        }
+        if (actionType == 'edit') {
+            if (publicData.currentActived) {
+                const { id } = publicData.currentActived;
+                publicData.editTreeHandle({ name: values.name, id: Number(id) });
+            }
+        }
+
+        setMccsModalVisible(false);
+
+    }
+
+
+    const onDrawerVisibleChangeHandle = (bool: boolean) => {
+        if (!bool) {
+            setSelectedRowIds([]); //关闭drawer清空
+            tableRef?.current?.getTableRef().current?.clearSelected(); //关闭Drawer清空选中项
+            setSelectedRowIds([]);
+            setSelectedFiles([]);
+        }
+        setDrawerVisible(bool);
+    }
+
+    const onSelectedFilesHandle = (selectedRowKeys: number[], selectedRows: any[]) => {
+        setSelectedFiles(selectedRows);
+    }
+
+    const drawerFormOnFinnish = async () => {
+
+        await publicData.batchConnectAccreditation({
+            articlesList: selectedRowIds,
+            ids: selectedFiles.map((t: any) => t.id)
+        });
+        setDrawerVisible(false);
+        tableRef?.current?.getTableRef().current?.clearSelected(); //关闭Drawer清空选中项
+        setSelectedRowIds([]);
+        setSelectedFiles([]);
+    }
+
+
+    const uploadFileHandle = async (file: any) => {
+        await publicData.uploadFilehandle(file);
+        setUploadModalVisible(false);
+    }
+
+    const batchDownload = (selectedRowKeys: string[] | number[]) => {
+        //   console.log({selectedRowKeys});
+        const toNumberArr = selectedRowKeys.map((t: string | number) => Number(t));
+        publicData.batchDownloadResourcePost(toNumberArr);
+    }
+
+
+
+    useEffect(() => {
+        //刷新表格数据
+        tableRef?.current?.getTableRef().current?.reload();
+    }, [publicData.reloadTable])
+
+    useEffect(() => {
+        //默认获取数据
+        publicData.getTreeData();
+    }, []);
+
+
+    return (
+        <MccsPageContainer>
+            <MccsDrawerForm
+                title='关联条款'
+                width={600}
+                visible={drawerVisible}
+                onVisibleChange={onDrawerVisibleChangeHandle}
+                onFinish={drawerFormOnFinnish}
+            >
+                <Form.Item>
+                    <MccsTable
+                        columns={drawerTableColumns}
+                        request={publicData.getDrawerTableList}
+                        search={{
+                            labelWidth: 0,
+                            span: 10
+                        }}
+                        rowSelection={{
+                            // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
+                            // 注释该行则默认不显示下拉选项
+                            selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+                            selectedRowKeys: [...selectedRowIds],
+                            onChange: (selectedRowKeys: number[]) => {
+                                setSelectedRowIds(selectedRowKeys);
+                            }
+                        }}
+                        rowKey="id"
+                        tableAlertOptionRender={({ selectedRowKeys, selectedRows, onCleanSelected }: { selectedRowKeys: number[] | string[], selectedRows: SelectedRowsType[], onCleanSelected: () => void }) => {
+
+                            return (
+                                <Space size={16}>
+                                    <Button type='primary' onClick={onCleanSelected}>取消选择</Button>
+                                </Space>
+                            );
+                        }}
+
+                    >
+
+                    </MccsTable>
+                </Form.Item>
+            </MccsDrawerForm>
+            {
+                MccsModalVisible && (
+                    <MccsModal
+                        title={actionType == 'add' ? '新增' : (actionType == 'edit' ? '编辑' : '')}
+                        visible={MccsModalVisible}
+                        layout='inline'
+                        initialValues={actionType == 'edit' && treeDataModelInit}
+                        onVisibleChange={MccsModalVisibleChangeHandle}
+                        onFinish={MccsModalFinnishHandle}
+                    >
+                        <Space size={20} direction='vertical'>
+                            <ProFormText
+                                name='name'
+                                width="md"
+                                label="名称"
+                                placeholder="请输入名称"
+                            />
+                            <ProFormSelect
+                                options={[
+                                    {
+                                        value: 1,
+                                        label: '等级评审',
+                                    },
+                                    {
+                                        value: 0,
+                                        label: '其他',
+                                    },
+                                ]}
+                                width="md"
+                                name="cateType"
+                                label="类型"
+                            />
+                        </Space>
+                    </MccsModal>
+                )
+            }
+
+            <MccsProCard gutter={16} ghost direction='row'>
+                <MccsProCard colSpan={6} style={{ height: '78vh' }} bodyStyle={{ padding: '16px' }}>
+                    <MccsFileTree
+                        treeData={publicData.treeData}
+                        //    defaultSelected={'0-0'}
+                        onSelectHandle={onSelectHandle}
+                        actionHandle={actionHandle}
+                        searchHandle={searchHandle}
+                        editable={true}
+                    />
+                </MccsProCard>
+                <MccsProCard colSpan={18} style={{ height: '78vh' }} bodyStyle={{ padding: '16px' }}>
+                    <MccsTable
+                        ref={tableRef}
+                        columns={columns}
+                        request={publicData.getTreeTableListHandle}
+                        search={{
+                            span: 8,
+                            optionRender: (searchConfig: any, formProps: any, dom: any) => [
+                                // <Button key='upload' onClick={uploadFileHandle}>上传文件</Button>,
+                                <MccsModal
+                                    title='标题'
+                                    key='upload'
+                                    visible={uploadModalVisible}
+                                    onVisibleChange={(bool: boolean) => setUploadModalVisible(bool)}
+                                    trigger={
+                                        <Button onClick={() => setUploadModalVisible(true)}>上传文件</Button>
+                                    }
+                                    onFinish={(values: { file: any }) => { uploadFileHandle(values.file.file) }}
+                                >
+                                    <Form.Item name='file'>
+                                        <MccsUpload />
+                                    </Form.Item>
+                                </MccsModal>,
+                                ...dom
+                            ]
+                        }}
+                        rowSelection={{
+                            // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
+                            // 注释该行则默认不显示下拉选项
+                            selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+                            onChange: (selectedRowKeys: any[], selectedRows: any[]) => { onSelectedFilesHandle(selectedRowKeys, selectedRows) }
+                        }}
+
+                        rowKey="id"
+                        tableAlertOptionRender={({ selectedRowKeys, selectedRows, onCleanSelected }: { selectedRowKeys: number[] | string[], selectedRows: SelectedRowsType[], onCleanSelected: () => void }) => {
+                            return (
+                                <Space size={16}>
+                                    <Button onClick={() => { connectHandle() }}>{`修改关联`}</Button>
+                                    <Button onClick={() => batchDownload(selectedRowKeys)}>{`下载`}</Button>
+                                    <Button type='ghost' onClick={onCleanSelected}>取消选择</Button>
+                                </Space>
+                            );
+                        }}
+                    />
+                </MccsProCard>
+            </MccsProCard>
+        </MccsPageContainer>
+    )
+}
+
+export default PublicData

+ 161 - 0
src/pages/DataManagement/publicData/model.ts

@@ -0,0 +1,161 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-23 09:02:09
+ * @LastEditTime: 2021-09-29 18:52:11
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/DataManagement/publicData/model.ts
+ */
+
+import { useState, useEffect } from 'react';
+import {
+  getTreeList,
+  getTreeTableList,
+  addTreeTableList,
+  editTreeTableList,
+  delTreeTableList,
+  getAllAccreditionLevelFourList,
+  connectAccreditation,
+  publicResourceUpload,
+  batchDownloadResource,
+  delTableFlieList,
+} from './serve';
+
+const publicData = () => {
+  const [treeData, setTreeData] = useState<MccsFileTree.childTree[]>([]);
+  const [currentActivedTree, setCurrentActivedTree] = useState<SelectedTreeDataType>();
+  const [currentActived, setCurrentActived] = useState<SelectedTreeDataType>();
+  const [reloadTable, setReloadTable] = useState(false);
+
+  const getTreeData = async (keyword?: string | number) => {
+    const data = await getTreeList(keyword);
+    setTreeData([data]);
+  };
+
+  const getTreeTableListHandle = async (params: {
+    keyword: string;
+    date: any;
+    current: number;
+    pageSize: number;
+  }) => {
+    //   console.log({params});
+    const { current, pageSize, keyword, date = [] } = params;
+    if (currentActivedTree) {
+      const { id, cateType } = currentActivedTree;
+      const resp = await getTreeTableList({
+        id: Number(id),
+        cateType: `${cateType}`,
+        current,
+        keyword,
+        pageSize,
+        startDate: date[0],
+        endDate: date[1],
+      });
+      const { list = [] } = resp;
+      return {
+        data: list,
+        success: true,
+      };
+    }
+  };
+
+  const addTreeHandle = async (formValue: API.AddTableListRequestType) => {
+    const resp = await addTreeTableList(formValue);
+    if (resp) {
+      getTreeData();
+    }
+  };
+
+  const editTreeHandle = async (formValue: API.EditTableListRequestType) => {
+    const resp = await editTreeTableList(formValue);
+    if (resp) {
+      getTreeData();
+    }
+  };
+
+  const delTreeHandle = async (ids: number[]) => {
+    const resp = await delTreeTableList(ids);
+    if (resp) {
+      getTreeData();
+    }
+  };
+
+  const delTableFlieListFunc = async (id:number)=>{
+       const resp = await delTableFlieList(id);
+       if(resp){
+        setReloadTable(true);
+       }
+  }
+
+  const getDrawerTableList = async (params:any) => {
+    const resp = await getAllAccreditionLevelFourList(params);
+    if (resp) {
+      return {
+        data: resp,
+        success: true,
+      };
+    }
+  };
+
+  const batchConnectAccreditation = async (data: API.BatchConnectAccreditation) => {
+      //批量关联条款
+    const resp = await connectAccreditation(data);
+    if (resp) {
+      setReloadTable(true);
+    }
+  };
+
+  const uploadFilehandle = async (files: { originFileObj: any; [key: string]: any }) => {
+    if (currentActivedTree) {
+      const { id } = currentActivedTree;
+      // console.log({files});
+      const resp = await publicResourceUpload({ id: Number(id), file: files.originFileObj });
+      if (resp) {
+        setReloadTable(true);
+      }
+    } else {
+      console.log('err', 'currentActivedTree', currentActivedTree, 'files', files);
+    }
+  };
+
+  const batchDownloadResourcePost = async (ids: number[]) => {
+      //批量下载
+    if (currentActivedTree) {
+      const { cateType } = currentActivedTree;
+      if (cateType != undefined) {
+        const resp = await batchDownloadResource(ids, cateType);
+        if (resp) {
+          let blob = new Blob([resp], { type: 'application/zip' });
+          let url = window.URL.createObjectURL(blob);
+          const link = document.createElement('a'); // 创建a标签
+          link.href = url;
+          link.click();
+          URL.revokeObjectURL(url); // 释放内存
+        }
+      }
+    }
+  };
+
+  useEffect(() => {}, [currentActivedTree]);
+
+  return {
+    treeData,
+    setTreeData,
+    getTreeData,
+    setCurrentActived,
+    currentActived,
+    delTreeHandle,
+    reloadTable,
+    uploadFilehandle,
+    setCurrentActivedTree,
+    getTreeTableListHandle,
+    addTreeHandle,
+    editTreeHandle,
+    getDrawerTableList,
+    batchConnectAccreditation,
+    batchDownloadResourcePost,
+    delTableFlieListFunc,
+  };
+};
+
+export default publicData;

+ 129 - 0
src/pages/DataManagement/publicData/serve.ts

@@ -0,0 +1,129 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-23 09:04:27
+ * @LastEditTime: 2021-09-29 18:40:55
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/DataManagement/publicData/serve.ts
+ */
+
+import { request } from 'umi';
+
+//获取公共资料树结构
+export const getTreeList  = (keyword?:string|number)=>{
+  
+    return request('/api/pfm/publicResource/list', {
+        method: 'GET',
+        params:{keyword}
+    });
+
+}
+
+//获取所有四码列表
+export const getAllAccreditionLevelFourList  = (params?:any)=>{
+  
+    return request('/api/pfm/publicresource/getNumStr', {
+        method: 'GET',
+        params:{...params}
+    });
+
+}
+
+//获取公共资料树结构对应表格数据
+export const getTreeTableList  = (data:API.GetTableListRequestType)=>{
+  
+    return request('/api/pfm/publicresource/getResourceList', {
+        method: 'GET',
+        params:{...data}
+    });
+
+}
+
+
+//新增公共资料树结构
+export const addTreeTableList  = (data:API.AddTableListRequestType)=>{
+  
+    return request('/api/pfm/publicResource/create', {
+        method: 'POST',
+        data:{...data}
+    });
+
+}
+
+//修改公共资料树结构
+export const editTreeTableList  = (data:API.EditTableListRequestType)=>{
+  
+    return request('/api/pfm/publicResource/update', {
+        method: 'POST',
+        data:{...data}
+    });
+
+}
+
+
+//关联条款
+export const connectAccreditation  = (data:API.BatchConnectAccreditation)=>{
+  
+    return request('/api/pfm/publicresource/updateBatchArticles', {
+        method: 'POST',
+        data:{...data}
+    });
+
+}
+
+//删除公共资料树结构
+export const delTreeTableList  = (id:number[])=>{
+  
+    return request('/api/pfm/publicResource/delete', {
+        method: 'POST',
+        data:id
+    });
+
+}
+
+//删除树结构对应的公共资料
+export const delTableFlieList  = (id:number)=>{
+  
+    return request('/api/pfm/publicresource/deleteResource', {
+        method: 'POST',
+        params:{id}
+    });
+
+}
+
+
+
+//公共资料上传
+export const publicResourceUpload  = (data:{file:any,id:number})=>{
+    let formData = new FormData();
+    formData.set('file',data.file);
+    formData.set('id',`${data.id}`);
+    return request('/api/pfm/publicresource/uploadPublicFile', {
+        method: 'POST',
+        data:formData
+    });
+
+}
+
+//删除公共资料
+export const delPublicResource  = (id:number[])=>{
+  
+    return request('/api/pfm/publicResource/delete', {
+        method: 'POST',
+        data:id
+    });
+
+}
+
+//公共资料批量下载
+export const batchDownloadResource  = (ids:number[],cateType:number)=>{
+  
+    return request('/api/pfm/publicResource/downloadCates', {
+        method: 'GET',
+        params:{
+            ids:ids.join(','),cateType
+        },
+        responseType:'blob'
+    });
+
+}

+ 46 - 0
src/pages/DataManagement/publicData/typings.d.ts

@@ -0,0 +1,46 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-23 15:02:19
+ * @LastEditTime: 2021-09-26 09:19:45
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/DataManagement/publicData/typings.d.ts
+ */
+
+type ArticlesList = {
+    ruleId:number,  //条文ID
+    ruleStr:string, //四码
+}
+
+interface SelectedTreeDataType extends MccsFileTree.childTree {
+    cateType?:number
+}
+
+declare namespace API {
+     type GetTableListRequestType = {
+        id:number,
+        cateType:string,
+        current?:number,
+        pageSize?:number,
+        keyword?:string,
+        fileType?:string,
+        startDate?:string,
+        endDate?:string
+     }
+
+     type AddTableListRequestType = {
+        parentId:number,
+        name:string,
+        cateType:number
+     }
+
+     type EditTableListRequestType = {
+        id:number,
+        name:string
+     }
+
+     type BatchConnectAccreditation = {
+        articlesList:number[],
+        ids:number[],
+     }
+}

+ 4 - 21
src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-10 11:44:42
- * @LastEditTime: 2021-09-14 17:04:04
+ * @LastEditTime: 2021-09-28 10:17:31
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/index.tsx
@@ -9,7 +9,7 @@
 
 
 
-import React, { useState, useEffect,useContext, ChangeEvent,forwardRef,useImperativeHandle, ReactNode } from 'react'
+import React, { useState, useEffect,useContext, ChangeEvent,forwardRef,useImperativeHandle } from 'react'
 import { Button, Image,Input } from 'antd';
 import { ProFormSelect } from '@ant-design/pro-form';
 import {
@@ -25,7 +25,7 @@ let FormList = forwardRef<FormList.FormListRefCurrent,FormList.FormListProps>((p
     const [data, setData] = useState<FormList.MapList[]>([]);
     const {formContext} = props;
     const providerData = useContext<MccsModal.MccsModalContextT>(formContext);
-    const {data:formListData} = props;
+    const {data:formListData,selecterList=[]} = props;
     // console.log({props,providerData});
 
 
@@ -145,24 +145,7 @@ let FormList = forwardRef<FormList.FormListRefCurrent,FormList.FormListProps>((p
                                     <Image width={15} preview={false} onClick={() =>formHandle('del',item.key)} src={'https://i.postimg.cc/HLkhvpBL/image.png'} />
                                 </span>
                                 <ProFormSelect
-                                    options={[
-                                        {
-                                            value: "A",
-                                            label: "A",
-                                        },
-                                        {
-                                            value: "B",
-                                            label: "B",
-                                        },
-                                        {
-                                            value: "C",
-                                            label: "C",
-                                        },
-                                        {
-                                            value: "D",
-                                            label: "D",
-                                        },
-                                    ]}
+                                    options={selecterList}
                                     fieldProps={{
                                         onChange:val=>selecterChangeHandle(val,index)
                                     }}

+ 7 - 1
src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/typings.d.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-13 17:47:42
- * @LastEditTime: 2021-09-13 17:47:43
+ * @LastEditTime: 2021-09-28 10:16:48
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/accreditationDetail/components/FormList/typings.d.ts
@@ -19,9 +19,15 @@ declare namespace FormList {
         }[],
         [propsName: string]: any
     }
+
+    type SelecterItem = {
+        label:string,
+        value:string|number
+    }
     
     type FormListProps = {
         data?: MapList[],
+        selecterList:SelecterItem[],
         onFinnish?:()=>void,
         [propsName: string]: any
     }

+ 21 - 16
src/pages/GradeHospitalAccreditation/accreditationDetail/index.less

@@ -1,6 +1,6 @@
-
 .rightCard {
   position: relative;
+
   .detailRuleTitle {
     height: 36px;
     font-size: 16px;
@@ -8,18 +8,22 @@
     font-weight: bold;
     color: #292C33;
     line-height: 36px;
+    overflow: hidden; //超出的文本隐藏
+    text-overflow: ellipsis; //用省略号显示
+    white-space: nowrap; //不换行
   }
-  
+
   .ruleDetailContainer {
     flex: 1;
-    height:calc(100% - 120px);
+    height: calc(100% - 120px);
     overflow: scroll;
+
     .ruleList {
       display: flex;
       flex-direction: column;
       justify-content: flex-start;
       margin-bottom: 24px;
-  
+
       .code {
         font-size: 16px;
         font-family: SourceHanSansCN-Normal, SourceHanSansCN;
@@ -27,7 +31,7 @@
         color: #7A8599;
         margin-bottom: 8px;
       }
-  
+
       .ruleTitle {
         font-size: 14px;
         font-family: SourceHanSansCN-Normal, SourceHanSansCN;
@@ -36,22 +40,23 @@
         line-height: 20px;
       }
     }
-  
+
     .scoreList {
       margin-bottom: 24px;
+
       .score {
         display: flex;
         flex-direction: row;
         justify-content: space-between;
         align-items: center;
-  
+
         .scoreVal {
           font-size: 16px;
           font-family: SourceHanSansCN-Bold, SourceHanSansCN;
           font-weight: bold;
           color: #292C33;
         }
-  
+
         .scoreSub {
           font-size: 12px;
           font-family: SourceHanSansCN-Normal, SourceHanSansCN;
@@ -59,7 +64,7 @@
           color: #FF9933;
         }
       }
-  
+
       .scoreCondition {
         width: 100%;
         background: #F7F8FA;
@@ -73,24 +78,24 @@
       }
     }
   }
-  
+
   .bottomActionBtnGroup {
     position: absolute;
     width: 100%;
-    left:0;
-    bottom:16px;
+    left: 0;
+    bottom: 16px;
     display: flex;
     flex-direction: row;
     padding: 0 24px;
     justify-content: space-between;
     align-items: center;
+
     .prev {
-        width: 30%;
+      width: 30%;
     }
+
     .next {
-        width: 68%;
+      width: 68%;
     }
   }
 }
-
-

+ 139 - 98
src/pages/GradeHospitalAccreditation/accreditationDetail/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-06 09:07:56
- * @LastEditTime: 2021-09-14 17:17:34
+ * @LastEditTime: 2021-09-29 18:11:36
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/accreditationDetail/index.tsx
@@ -13,7 +13,7 @@
 import React, { useState, useEffect, useRef } from 'react'
 import { Divider, Button } from 'antd'
 import MccsProFormText from '@/components/antdProOverwrite/MccsProFormText/index';
-import {MccsModalContext,MccsModal} from '@/components/MccsModal/index';
+import { MccsModalContext, MccsModal } from '@/components/MccsModal/index';
 import MccsPageContainer from '@/components/MccsPageContainer/index'
 import MccsProCard from '@/components/MccsProCard/index';
 import MccsFileTree from '@/components/MccsFileTree/index';
@@ -58,7 +58,7 @@ type ruleList = {
 const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = props => {
 
   const { accreditationDetail } = useModel('allModels');
-  const { getTreeData,treeData,delDetailRuleHandle,addDetailRuleHandle,editDetailRulehandle,detailRuleList,getDetailRuleListHandle } = accreditationDetail();
+  const { getTreeData, treeData, delDetailRuleHandle, addDetailRuleHandle, editDetailRulehandle, detailRuleList, getDetailRuleListHandle, setDetailRuleList,...restAccreditationModel } = accreditationDetail;
 
 
   const [mode, setMode] = useState(1); //1,2
@@ -67,15 +67,16 @@ const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = p
   const [childRuleList, setChildRuleList] = useState<ruleList>([]);
   const [modalVisible, setModalVisible] = useState(false);
   const [actionType, setActionType] = useState('add');
-  const formListRef = useRef<FormList.FormListRefCurrent>(null); 
-
-  const [formDefaultData,setFormDefaultData] = useState<any>(undefined);
+  const formListRef = useRef<FormList.FormListRefCurrent>(null);
 
+  const [formDefaultData, setFormDefaultData] = useState<any>(undefined);
+  const [defaultOpened, setDefaultOpened] = useState<string>();
+  
 
   const onSelectHandle = (data: treeItem) => {
 
     setCurrentActived(data);  //设置当前树数据
-    const { isLeaf, children,id } = data;
+    const { isLeaf, children, id } = data;
 
     if (isLeaf) {
       //叶子结点
@@ -93,25 +94,26 @@ const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = p
     }
   }
   //操作回调
-  const actionHandle = ({ type, data }: { type: string, data:treeItem|null}) => {
+  const actionHandle = ({ type, data }: { type: string, data: treeItem | null }) => {
 
-    data?setCurrentActived(data):setCurrentActived(undefined);  //点击获取当前树数据
+    data ? setCurrentActived(data) : setCurrentActived(undefined);  //点击获取当前树数据
 
-    if(type=='del'){
+    if (type == 'del') {
       //删除
       setActionType('del');
-      if(data){
-        const {id} = data;
+      if (data) {
+        const { id } = data;
         delDetailRuleHandle(id);
       }
-      
+
     }
-    if(type == 'edit'){
+    if (type == 'edit') {
       setActionType('edit');
-      data&&setFormDefaultData(data);
+      data && setFormDefaultData(data);
       setModalVisible(true);
     }
-    if(type == 'add'){
+    if (type == 'add') {
+      setDetailRuleList([]);
       setActionType('add');
       setModalVisible(true);
     }
@@ -127,120 +129,141 @@ const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = p
 
     const [showMore, setShowMore] = useState(false);
     const [list, setList] = useState<API.RuleDetailListItem[]>([]);  //
-    
+    const [selecterList,setSelecterList] = useState<FormList.SelecterItem[]>([]);
 
-    const formNodeSubmitHandle = (values:any) => {
+
+    const formNodeSubmitHandle = (values: any) => {
       // console.log('表单', values);
       // console.log({formListRef});
 
-      const {name} = values;
+      const { name, numStr } = values;
       let parentId = 0;
-      if(currentActived){
-        const {id} = currentActived;
+      if (currentActived) {
+        const { id } = currentActived;
         parentId = Number(id);
       }
-      
-      if(actionType=='add'){
 
-        let details:any = [];
-        const {levelNum=0 } = currentActived?currentActived:{};
-        console.log({currentActived});
-        if(formListRef.current&&levelNum==3){
+      if (actionType == 'add') {
+
+        let details: any = [];
+        const { levelNum = 0 } = currentActived ? currentActived : {};
+        if (formListRef.current && levelNum == 3) {
           //当是新增叶子结点,也就是增加第4层
           setShowMore(true);
           const tempArr = formListRef.current.getData();
-          // console.log({tempArr});
-          details = tempArr.map(item=>{
-             const {list,evaluation} = item;
-             const tempList = list.map(val=>({title:val.detail}));
-             return {
+          details = tempArr.map(item => {
+            const { list, evaluation } = item;
+            const tempList = list.map(val => ({ title: val.detail }));
+            return {
               evaluation,
-              detail:tempList
-             }
+              detail: tempList
+            }
           })
-           
-      }
+
+        }
         const paramData = {
           parentId,
-          name:name,
-          detail:details
+          name: name,
+          numStr:numStr,
+          detail: details
         }
         addDetailRuleHandle(paramData);
       }
 
-      if(actionType=='edit'){
-        
-        if(currentActived){
-          const {id,isLeaf} = currentActived;
-          let details:any = [];
-          if(formListRef.current&&isLeaf){
-              //当是叶子结点
-              const tempArr = formListRef.current.getData();
-              // console.log({tempArr});
-              details = tempArr.map(item=>{
-                 const {list,evaluation} = item;
-                 const tempList = list.map(val=>({title:val.detail}));
-                 return {
-                  evaluation,
-                  detail:tempList
-                 }
-              })
-               
+      if (actionType == 'edit') {
+
+        if (currentActived) {
+          const { id, isLeaf } = currentActived;
+          let details: any = [];
+          if (formListRef.current && isLeaf) {
+            //当是叶子结点
+            const tempArr = formListRef.current.getData();
+            // console.log({tempArr});
+            details = tempArr.map(item => {
+              const { list, evaluation } = item;
+              const tempList = list.map(val => ({ title: val.detail }));
+              return {
+                evaluation,
+                detail: tempList
+              }
+            })
+
           }
           const paramData = {
-            id:Number(id),
-            name:name,
-            detail:isLeaf?details:[],
+            id: Number(id),
+            name: name,
+            detail: isLeaf ? details : [],
           }
           editDetailRulehandle(paramData);
         }
       }
-      
       setModalVisible(false);
+      return true;
     }
 
     const formNodeVisibleHandle = (bool: boolean) => {
-      
-      !bool&&setCurrentActived(undefined);  //关闭弹窗清除
+
+      !bool && setCurrentActived(undefined);  //关闭弹窗清除
       setModalVisible(bool);
     }
 
+  
     useEffect(() => {
       if (currentActived) {
-     
-        const { isLeaf,levelNum } = currentActived;
 
-        isLeaf&&setShowMore(true);//当新增或编辑第4层时也就是叶子节点,增加表单数据
-        (levelNum==3&&actionType=='add') && setShowMore(true);  //当新增或编辑第4层时也就是叶子节点,增加表单数据
+        const { isLeaf, levelNum } = currentActived;
+
+        isLeaf && setShowMore(true);//当新增或编辑第4层时也就是叶子节点,增加表单数据
+        (levelNum == 3 && actionType == 'add') && setShowMore(true);  //当新增或编辑第4层时也就是叶子节点,增加表单数据
+
+        if(isLeaf||(levelNum == 3 && actionType == 'add')){
+                //展示子集时才请求
+          restAccreditationModel.getScoreSelectableList().then(data=>{
+            const tempArr = data.map((t:any)=>({label:t.levelNumber,value:t.levelNumber}));
+            setSelecterList(tempArr);
+          })
+        }
+    
       }
     }, [currentActived]);
 
+    
 
-    useEffect(()=>{
+    useEffect(() => {
       setList(detailRuleList);
-    },[]);
+    }, []);
 
 
     return (
-      <MccsModal title={actionType=='edit'?'编辑评审细则':'新增评审细则'} visible={visible} onVisibleChange={formNodeVisibleHandle}
-        initialValues={actionType=='edit'?{...formDefaultData,name:formDefaultData.title}:{}}
-        onFinish={formNodeSubmitHandle} modalProps={{ destroyOnClose: true }} 
+      <MccsModal title={actionType == 'edit' ? '编辑评审细则' : '新增评审细则'} visible={visible} onVisibleChange={formNodeVisibleHandle}
+        initialValues={actionType == 'edit' ? { ...formDefaultData, name: formDefaultData.title, numStr: formDefaultData.code } : {}}
+        onFinish={formNodeSubmitHandle}
       >
         <MccsProFormText
           width="md"
           name="name"
-          label="评审名"
+          label="内容"
           placeholder="请输入名称"
         />
+        {
+          actionType == 'add' && (
+            <MccsProFormText
+              width="md"
+              name="numStr"
+              label="四码"
+              placeholder="请输入名称"
+            />
+          )
+        }
         {
           showMore && (
             <ProForm.Item
-              label="数组数据"
+              label="等级明细"
               name="dataSource"
               // initialValue={defaultData}
               trigger="onValuesChange"
             >
-              <FormList data={list} ref={formListRef} formContext = {MccsModalContext} />
+              <FormList data={list} selecterList={selecterList} ref={formListRef} formContext={MccsModalContext} />
             </ProForm.Item>
           )
         }
@@ -249,21 +272,39 @@ const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = p
   }
 
 
+  useEffect(() => {
+    if (treeData.length > 0) {
+      //默认展开书结构第一个结点
+      const { id } = treeData[0];
+      setDefaultOpened(`${id}`);
+    }
+  }, [treeData]);
+
+  useEffect(() => {
+    getTreeData();
+  }, []);
+
+
   return (
     <MccsPageContainer>
 
-      {<FormNode visible={modalVisible} />}
+      {modalVisible&&<FormNode visible={modalVisible} />}
 
       <MccsProCard gutter={16} ghost direction='row'>
         <MccsProCard colSpan={14} style={{ height: '78vh' }} bodyStyle={{ padding: '16px' }}>
-          <MccsFileTree
-            treeData={treeData}
-            defaultSelected={'0-0'}
-            onSelectHandle={onSelectHandle}
-            actionHandle={actionHandle}
-            searchHandle={searchHandle}
-            editable={true}
-          />
+          {
+            defaultOpened && (
+              <MccsFileTree
+                treeData={treeData}
+                defaultSelected={defaultOpened}
+                onSelectHandle={onSelectHandle}
+                actionHandle={actionHandle}
+                searchHandle={searchHandle}
+                editable={true}
+              />
+            )
+          }
+
         </MccsProCard>
         <MccsProCard colSpan={10} className='rightCard' style={{ height: '78vh', overflow: 'hidden' }} >
           <div className="detailRuleTitle">{currentActived?.title}</div>
@@ -288,37 +329,37 @@ const AccreditationDetail: React.FunctionComponent<AccreditationDetailProps> = p
             {
               mode == 2 && (
                 <>
-                  
+
                   {
-                    detailRuleList.map((item,index)=>{
-                        return (
-                          <div className='scoreList' key={index}>
+                    detailRuleList.map((item, index) => {
+                      return (
+                        <div className='scoreList' key={index}>
                           <div className='score'>
                             <span className='scoreVal'>{`${item.evaluation}:`}</span>
                             <span className='scoreSub'>{`符合“${item.evaluation}”并具备以下要求`}</span>
                           </div>
                           <div className='scoreCondition' >
-                                {
-                                  item.detail.map((val,i)=>{
-                                       return (
-                                           <div key={i}>{val.title}</div>
-                                       )
-                                  })
-                                }
+                            {
+                              item.detail.map((val, i) => {
+                                return (
+                                  <div key={i}>{val.title}</div>
+                                )
+                              })
+                            }
                           </div>
                         </div>
-                        )
+                      )
                     })
                   }
-           
+
                 </>
               )
             }
           </div>
-          <div className='bottomActionBtnGroup'>
+          {/* <div className='bottomActionBtnGroup'>
             <Button className='prev'>上一项</Button>
             <Button className='next' type='primary'>下一项</Button>
-          </div>
+          </div> */}
         </MccsProCard>
       </MccsProCard>
     </MccsPageContainer>

+ 16 - 9
src/pages/GradeHospitalAccreditation/accreditationDetail/model.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-06 17:42:57
- * @LastEditTime: 2021-09-14 09:05:32
+ * @LastEditTime: 2021-09-28 10:28:42
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/accreditationDetail/model.ts
@@ -9,11 +9,13 @@
 
 // accreditationDetail
 
-import { useState, useEffect } from 'react';
+import { useState } from 'react';
 import { getTreeList, delDetailRule, addDetailRule,editDetailRule,getDetailRuleList } from './service';
+import {getScoreLevelData} from '@/pages/PlatformMana/generalSetting/serve';
+
 
 const accreditationDetail = () => {
-  const [treeData, setTreeData] = useState([]);
+  const [treeData, setTreeData] = useState<MccsFileTree.childTree[]>([]);
   const [detailRuleList,setDetailRuleList] = useState<API.DetailRuleList[]>([]);
 
   const getTreeData = async (keyword?:string|number) => {
@@ -35,8 +37,11 @@ const accreditationDetail = () => {
   };
 
   const editDetailRulehandle = async (data:API.EditDetailRule)=>{
-     await editDetailRule(data);
-     getTreeData();
+     const resp = await editDetailRule(data);
+     if(resp){
+      getTreeData(); //更新树
+      getDetailRuleListHandle(data.id); //重新获取
+     }
   }
 
   const getDetailRuleListHandle = async (id:number|string)=>{
@@ -44,13 +49,15 @@ const accreditationDetail = () => {
      setDetailRuleList(leafDetails);
   }
 
-  useEffect(() => {
-    getTreeData();
-  }, []);
+  const getScoreSelectableList = async ()=>{
+     //获取表单下拉评分数据
+     return await getScoreLevelData();
+  }
+
 
   return { 
     treeData, setTreeData, getTreeData, delDetailRuleHandle, addDetailRuleHandle,
-    editDetailRulehandle ,detailRuleList,getDetailRuleListHandle
+    editDetailRulehandle ,detailRuleList,getDetailRuleListHandle,setDetailRuleList,getScoreSelectableList
   };
 };
 

+ 18 - 0
src/pages/GradeHospitalAccreditation/articleManagement/index.less

@@ -51,6 +51,24 @@
   }
 }
 
+.selfEvolutionArea {
+  text-align: center;
+  line-height: 50px;
+  background: #FFFFFF;
+  border-radius: 25px;
+  border: 1px dashed #DADEE6;
+  margin-top: 40px;
+  margin-bottom: 40px;
+  padding: 10px;
+  .selfEvolutionTitle {
+       text-align: left;
+       font-size: 16px;
+        font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+        font-weight: 400;
+        color: #7A8599;
+
+  }
+}
 
 .formItemTitle {
     font-size: 16px;

+ 290 - 98
src/pages/GradeHospitalAccreditation/articleManagement/index.tsx

@@ -1,14 +1,14 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 10:22:09
- * @LastEditTime: 2021-09-16 17:52:55
+ * @LastEditTime: 2021-09-29 16:45:01
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/index.tsx
  */
 
 
-import React, {useRef,useEffect } from 'react'
+import React, { useRef, useEffect, useState } from 'react'
 import MccsPageContainer from '@/components/MccsPageContainer/index'
 import MccsProCard from '@/components/MccsProCard/index';
 import { useModel } from 'umi';
@@ -18,20 +18,28 @@ import MccsScoreBanner from '@/components/MccsScoreBanner/index';
 import MccsRecordList from '@/components/MccsRecordList/index';
 import MccsDrawerForm from '@/components/MccsDrawerForm/index';
 import MccsClickableTabs from '@/components/MccsClickableTabs/index';
+import MccsUpload from '@/components/MccsUpload/index';
+import { MccsModal } from '@/components/MccsModal';
 
 
-import { Form, Table, Space, Row, Col, Button } from 'antd'
+
+import { Form, Table, Space, Row, Col, Button, Tabs } from 'antd'
 import {
     ProFormText,
     ProFormSelect,
-    ProFormDependency
+    ProFormDependency,
 } from '@ant-design/pro-form';
 
 
 import './index.less';
 
 
+
 type ArticleManagementProps = {
+    //组件配置信息
+    columnsFromProps?: {}[],
+    headerConcig?: { [key: string]: any }, //配置参考ProPageContainer
+    isModeTwo?: boolean
 
 }
 
@@ -39,7 +47,10 @@ type SelectedRowsType = {
     [propsName: string]: any
 }
 
+const { TabPane } = Tabs;
+
 const columns = [
+
     {
         key: 'keyword',
         hideInTable: true,
@@ -66,7 +77,8 @@ const columns = [
         title: '条文',
         dataIndex: 'name',
         hideInSearch: true,
-        width: '35%'
+        width: '35%',
+        ellipsis:true
     },
     {
         title: '负责单位',
@@ -102,7 +114,7 @@ const columns = [
 
 //条文管理
 const ArticleManagement: React.FC<ArticleManagementProps> = (props) => {
-
+    const { columnsFromProps = [], headerConcig, isModeTwo } = props;
     const { articleManagement } = useModel('allModels');
     const {
         isLeaf,
@@ -115,21 +127,22 @@ const ArticleManagement: React.FC<ArticleManagementProps> = (props) => {
         departmentManagers,
         getDepartment,//获取责任单位
         ...restModelData
-    } = articleManagement();
+    } = articleManagement;
     const tableRef = useRef<MccsTable.MccsTableRef>();
-    const btnRef = useRef<HTMLButtonElement>();  //取消批量按钮
+
+    const [articleSettingFormInit, setArticleSettingFormInit] = useState<{}>({});  //条文设置表单回显默认值
+
+    const [uploadLedgerTypeList,setUploadLedgerTypeList] = useState<MccsClickableTabs.TabType[]>([]);
 
 
     const onSelectHandle = (data: MccsFileTree.childTree) => {
         setCurrentActivedTree(data);
-
         //重新获取数据
         tableRef?.current?.getTableRef().current?.reload();
     }
 
-    const batchSelfAssessment = (rowkeys:number[]|string[]) => {
+    const batchSelfAssessment = (rowkeys: number[] | string[]) => {
         //批量设置
-     
         restModelData.setDrawerFormType('BATCHSETTING');
         restModelData.setSelectedRowKeys(rowkeys);
         restModelData.setDrawerVisible(true);
@@ -137,100 +150,233 @@ const ArticleManagement: React.FC<ArticleManagementProps> = (props) => {
 
     const articleSetBtnHandle = () => {
         //条文设置
+        // console.log({ articleSettingFormInit });
+        restModelData.setDrawerFormType('ARTICLE_SET');
         restModelData.setDrawerVisible(true);
-        
+
     }
 
     const onVisibleChangeHandle = (visible: boolean) => {
+        //drawer展示控制
         restModelData.setDrawerVisible(visible);
     }
 
+    const onModalVisibleChange = (visible: boolean) => {
+        //表单弹窗
+        //  console.log('uploadFormInitValue',restModelData.uploadFormInitValue);
+        !visible && restModelData.setUploadFormInitValue(undefined);
+        restModelData.setModalVisible(visible);
+
+    }
+
+    const upLoadFileHandle = (formInitData?: any) => {
+        //因为modalForm开启了request+params获取表单默认值,
+        //所以必须先设置默认值才能开启弹窗
+        if (formInitData) {
+            const { fileUrl, recordTypeName, fileName } = formInitData;
+            restModelData.setUploadFormInitValue({
+                tab:recordTypeName,
+                files: [{
+                    uid: new Date().getTime(),
+                    name: fileName,
+                    status: 'done',
+                    url: fileUrl
+                }]
+            });
+        } else {
+            restModelData.setUploadFormInitValue({})
+        }
+        restModelData.getUploadLedgerType().then(data=>{
+            //设置上传台账类型
+            setUploadLedgerTypeList(data);
+          
+        })
+        restModelData.setModalVisible(true);
+    }
+
+    const actionNodeFunc = (data: any) => {
+        //渲染记录列表操作按钮
+        // console.log({ data });
+        const { fileUrl } = data;
+        const reupload = () => {
+
+            upLoadFileHandle(data);
+        }
+
+        return isModeTwo ? (
+            //台账上传
+            <a onClick={reupload}>重新上传</a>
+        ) : (
+            //条文管理
+            <a href={fileUrl}>下载文件</a>
+        )
+    }
+
+
+    const uploadLedgerChangeHandle = (tabData:any)=>{
+         //台账上传类型选择回调
+         console.log({tabData});
+    }
+
+
     useEffect(() => {
-    
-        if(restModelData.reloadRightContent){
-              //重新获取数据
-           tableRef?.current?.getTableRef().current?.reload();
-           tableRef?.current?.getTableRef().current?.clearSelected();
+
+        if (restModelData.reloadRightContent) {
+            //重新获取数据
+            tableRef?.current?.getTableRef().current?.reload();
+            tableRef?.current?.getTableRef().current?.clearSelected();
         }
     }, [restModelData]);
 
-  
+
+    useEffect(() => {
+        if (restModelData.leafData) {
+            const { responsibilityDepartmentId,responsibilityDepartmentName, responsibilityUserId, targetEvaluation,responsibilityUserName } = restModelData.leafData;
+            setArticleSettingFormInit({
+                responsibilityDepartment:{label:responsibilityDepartmentName,value:responsibilityDepartmentId},
+                responsibilityUser: {label:responsibilityUserName,value:responsibilityUserId},
+                targetScores: targetEvaluation,
+                articleType: 'A'
+            });
+        }
+
+    }, [restModelData.leafData]);
+
+
+    useEffect(() => {
+        if (isModeTwo) {
+            //设置当前模块模式
+            restModelData.setModuleMode(isModeTwo);
+        } else {
+            //设置当前模块模式
+            restModelData.setModuleMode(false);
+        }
+    }, [props]);
+
+    useEffect(() => {
+        restModelData.getArticleTreeData();
+    }, [])
 
     return (
-        <MccsPageContainer>
-            <MccsDrawerForm
-                title={restModelData.drawerFormType=='ARTICLE_SET'?'条文设置':'批量设置'}
-                width={500}
-                visible={restModelData.drawerVisible}
-
-                onFinish={(values: any) => restModelData.drawerFormType=='ARTICLE_SET'?restModelData.setArticle(values):restModelData.batchSetting(values)}
-                onVisibleChange={onVisibleChangeHandle}
-            >
-                <div className='formItemTitle'>负责人及单位</div>
-                <Row gutter={16}>
-                    <Col className="gutter-row" span={8}>
-                        <ProFormSelect
-                            name="responsibilityDepartment"
-                            width='sm'
-                            request={getDepartmentRequest}
-                            placeholder="选择单位"
-                            fieldProps={{
-                                labelInValue: true,
-                                onChange: (value, option) => getDepartment(value, option)
-                            }}
-                            rules={[{ required: true, message: '请选择单位!' }]}
-                        />
-                    </Col>
-
-                    <Col className="gutter-row" span={8}>
-                        <ProFormDependency name={['responsibilityDepartment']}>
-                            {({ responsibilityDepartment }) => {
-                                return (
-                                    <ProFormSelect
-                                        name="responsibilityUser"
-                                        width='sm'
-                                        disabled={!responsibilityDepartment}
-                                        options={departmentManagers}
-                                        placeholder="选择负责人"
-                                        fieldProps={{
-                                            labelInValue: true,
-                                            // onChange:(value,option)=>getManagers(value,option)
-                                        }}
-                                        rules={[{ required: true, message: '请选择负责人!' }]}
-                                    />
-                                )
-                            }}
-                        </ProFormDependency>
-                    </Col>
-                </Row>
-                <div className='formItemTitle'>目标分数</div>
-                <Row >
-                    <Col span={24}>
-                        <Form.Item name='targetScores'>
+        <MccsPageContainer
+            config={headerConcig ? headerConcig : {}}
+        >
+            {
+                restModelData.modalVisible && (
+                    <MccsModal title='台账上传' visible={restModelData.modalVisible}
+                        onFinish={(values: any) => restModelData.uploadFile(values)}
+                        initialValues={restModelData.uploadFormInitValue}
+                        onVisibleChange={onModalVisibleChange}
+                        params={restModelData.uploadFormInitValue}
+                        request={(params: any) => {
+                            return Promise.resolve(params)
+                        }}
+                    >
+                        <div className='formItemTitle'>选择类型</div>
+                        <Form.Item name='tab' rules={[
+                            {
+                                required: true,
+                                message: '请选择类型!',
+                            },
+                        ]}>
                             <MccsClickableTabs
-                                data={restModelData.targetScores}
+                                disabled={(restModelData.uploadFormInitValue && JSON.stringify(restModelData.uploadFormInitValue) != '{}') ? true : false}
+                                type='multi'
+                                onChange={uploadLedgerChangeHandle}
+                                data={uploadLedgerTypeList}
                             />
                         </Form.Item>
-                    </Col>
-                </Row>
-                {
-                    true && (
-                        <>
-                            <div className='formItemTitle'>条文组别</div>
-                            <Row>
-                                <Col span={24}>
-                                    <Form.Item name='articleType'>
-                                        <MccsClickableTabs
-                                            data={restModelData.ruleTypes}
-                                        />
-                                    </Form.Item>
-                                </Col>
-                            </Row>
-                        </>
-                    )
-                }
-
-            </MccsDrawerForm>
+                        <Form.Item name='files' rules={[
+                            {
+                                required: true,
+                                message: '请上传文件!',
+                            },
+                        ]}>
+                            <MccsUpload maxCount={1} />
+                        </Form.Item>
+                    </MccsModal>
+                )
+            }
+
+            {
+                //条文设置/表格批量设置drawer弹窗
+                restModelData.drawerVisible  && (
+                    <MccsDrawerForm
+                        title={restModelData.drawerFormType == 'ARTICLE_SET' ? '条文设置' : '批量设置'}
+                        width={500}
+                        visible={restModelData.drawerVisible}
+                        initialValues={restModelData.drawerFormType == 'ARTICLE_SET' ? { ...articleSettingFormInit } : {}}
+                        onFinish={(values: any) => restModelData.drawerFormType == 'ARTICLE_SET' ? restModelData.setArticle(values) : restModelData.batchSetting(values)}
+                        onVisibleChange={onVisibleChangeHandle}
+                    >
+                        <div className='formItemTitle'>负责人及单位</div>
+                        <Row gutter={16}>
+                            <Col className="gutter-row" span={8}>
+                                <ProFormSelect
+                                    name="responsibilityDepartment"
+                                    width='sm'
+                                    request={getDepartmentRequest}
+                                    placeholder="选择单位"
+                                    fieldProps={{
+                                        labelInValue: true,
+                                        onChange: (value, option) => getDepartment(value, option)
+                                    }}
+                                    rules={[{ required: true, message: '请选择单位!' }]}
+                                />
+                            </Col>
+
+                            <Col className="gutter-row" span={8}>
+                                <ProFormDependency name={['responsibilityDepartment']}>
+                                    {({ responsibilityDepartment }) => {
+                                        return (
+                                            <ProFormSelect
+                                                name="responsibilityUser"
+                                                width='sm'
+                                                disabled={!responsibilityDepartment || JSON.stringify(responsibilityDepartment) == '{}'}
+                                                options={departmentManagers}
+                                                placeholder="选择负责人"
+                                                fieldProps={{
+                                                    labelInValue: true,
+                                                    // onChange:(value,option)=>getManagers(value,option)
+                                                }}
+                                                rules={[{ required: true, message: '请选择负责人!' }]}
+                                            />
+                                        )
+                                    }}
+                                </ProFormDependency>
+                            </Col>
+                        </Row>
+                        <div className='formItemTitle'>目标分数</div>
+                        <Row >
+                            <Col span={24}>
+                                <Form.Item name='targetScores'>
+                                    <MccsClickableTabs
+                                        data={restModelData.targetScores}
+                                    />
+                                </Form.Item>
+                            </Col>
+                        </Row>
+                        {
+                            true && (
+                                <>
+                                    <div className='formItemTitle'>条文组别</div>
+                                    <Row>
+                                        <Col span={24}>
+                                            <Form.Item name='articleType'>
+                                                <MccsClickableTabs
+                                                    data={restModelData.ruleTypes}
+                                                />
+                                            </Form.Item>
+                                        </Col>
+                                    </Row>
+                                </>
+                            )
+                        }
+
+                    </MccsDrawerForm>
+
+                )
+            }
 
             <MccsProCard gutter={16} ghost direction='row'>
                 <MccsProCard colSpan={6} style={{ height: '78vh' }} bodyStyle={{ padding: '16px' }}>
@@ -248,19 +394,22 @@ const ArticleManagement: React.FC<ArticleManagementProps> = (props) => {
                         !isLeaf && (
                             <MccsTable
                                 ref={tableRef}
-                                columns={columns}
+                                columns={columnsFromProps.length > 0 ? columnsFromProps : columns}
                                 request={getTableData}
+                                search={{
+                                    span: 6
+                                }}
                                 rowSelection={{
                                     // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
                                     // 注释该行则默认不显示下拉选项
                                     selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
                                 }}
                                 rowKey="id"
-                                tableAlertOptionRender={({selectedRowKeys, selectedRows,onCleanSelected}:{selectedRowKeys:number[]|string[],selectedRows:SelectedRowsType[],onCleanSelected:()=>void}) => {
+                                tableAlertOptionRender={({ selectedRowKeys, selectedRows, onCleanSelected }: { selectedRowKeys: number[] | string[], selectedRows: SelectedRowsType[], onCleanSelected: () => void }) => {
                                     return (
                                         <Space size={16}>
                                             <Button type='primary' onClick={() => batchSelfAssessment(selectedRowKeys)}>批量设置</Button>
-                                            <Button  type='ghost' onClick={onCleanSelected}>取消选择</Button>
+                                            <Button type='ghost' onClick={onCleanSelected}>取消选择</Button>
                                         </Space>
                                     );
                                 }}
@@ -275,18 +424,61 @@ const ArticleManagement: React.FC<ArticleManagementProps> = (props) => {
                                 <div className='leafContentTitle'>{currentActivedTree ? currentActivedTree.title : ''}</div>
                                 <div className='peopleGroup'>
                                     <span>条文组别:</span>
-                                    <span>{restModelData.leafData?.articleType}</span>
+                                    <span>{restModelData.leafData?.accountType}</span>
                                     <span>负责单位:</span>
                                     <span>{restModelData.leafData?.responsibilityDepartmentName}</span>
                                     <span>负责人:</span>
                                     <span>{restModelData.leafData?.responsibilityUserName}</span>
                                 </div>
                                 <MccsScoreBanner list={scoreList} />
-                                <div className='articleSetBtn'><span onClick={articleSetBtnHandle}>条文设置</span></div>
-                                <MccsRecordList
-                                    title='台账记录'
-                                    list={[]}
-                                />
+                                {
+                                    isModeTwo && (
+                                        <div style={{ marginTop: 5 }}>
+                                            <Tabs defaultActiveKey="1" centered size='large' onChange={(key) => restModelData.setTabKey(key)}>
+                                                <TabPane tab="台账记录" key="1">
+                                                    <div className='articleSetBtn'>
+                                                        <span onClick={() => upLoadFileHandle()}>上传文件</span>
+                                                    </div>
+                                                    <MccsRecordList
+                                                        title='台账记录'
+                                                        list={restModelData.records}
+                                                        actionFunc={(data)=>restModelData.delHistoryRecordHandle(data)}
+                                                        actionNode={(data) => actionNodeFunc(data)}
+                                                    />
+                                                </TabPane>
+                                                <TabPane tab="自评结果" key="2">
+                                                    <div className='selfEvolutionArea'>
+                                                        <div className='selfEvolutionTitle'>开始自评</div>
+                                                        <MccsClickableTabs
+                                                            onChange={(value: string| number| null) => restModelData.onSelfEvolutionTabChange(value)}
+                                                            data={restModelData.targetScores}
+                                                            value={restModelData.selectedSelfEvolution}
+                                                        />
+                                                        <Button onClick={() => restModelData.commitSelfEvolution()}>提交自评</Button>
+                                                    </div>
+                                                    <MccsRecordList
+                                                        title='自评记录'
+                                                        list={restModelData.selfEvaluationRecords}
+                                                    />
+                                                </TabPane>
+                                            </Tabs>
+                                        </div>
+                                    )
+                                }
+                                {
+                                    !isModeTwo && (
+                                        <>
+                                            <div className='articleSetBtn'><span onClick={articleSetBtnHandle}>条文设置</span></div>
+                                            <MccsRecordList
+                                                title='台账记录'
+                                                list={restModelData.records}
+                                                actionFunc={(data)=>{console.log({data})}}
+                                                //restModelData.delHistoryRecordHandle(data)
+                                                actionNode={(data) => actionNodeFunc(data)}
+                                            />
+                                        </>
+                                    )
+                                }
                             </div>
                         )
                     }

+ 274 - 65
src/pages/GradeHospitalAccreditation/articleManagement/model.ts

@@ -1,20 +1,19 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 10:46:45
- * @LastEditTime: 2021-09-16 17:49:53
+ * @LastEditTime: 2021-09-29 17:39:50
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/model.ts
  */
 
-import { useState, useEffect,Key } from 'react';
-import { getTreeFileTableData,getDepartmentList,settingArticle,batchSettingArticle } from './server';
+import { useState, useEffect } from 'react';
+import { getTreeFileTableData,getDepartmentList,settingArticle,batchSettingArticle,getSelfEvaluation,
+  uploadFilePost,selfEvolutionCommit,delHistoryRecods,getUploadLedgerSelectableType,
+} from './server';
 import {getTreeList} from '@/pages/GradeHospitalAccreditation/accreditationDetail/service';
-
-
-
-
-
+import {getScoreLevelData,getAccreditationTypeData} from '@/pages/PlatformMana/generalSetting/serve';
+import { notification } from 'antd';
 
 //articleManagement
 const articleManagement = () => {
@@ -28,8 +27,8 @@ const articleManagement = () => {
   const [selectedDepartment,setSelectedDepartment] = useState<any>();
   const [targetScores,setTargetScores] = useState<MccsClickableTabs.TabType[]>([]);
   const [ruleTypes,setRuleTypes] = useState<MccsClickableTabs.TabType[]>([]);
-  const [records,setRecords]=useState<MccsRecordList.MccsRecordListType>();
-
+  const [records,setRecords]=useState<MccsRecordList.MccsRecordListType>([]);
+  const [selfEvaluationRecords,setSelfEvaluationRecords] = useState<MccsRecordList.MccsRecordListType>([]);  //自评记录
   const [selectedRowKeys,setSelectedRowKeys] = useState<number[]|string[]>([]);
 
   const [drawerVisible, setDrawerVisible] = useState(false);
@@ -37,19 +36,46 @@ const articleManagement = () => {
 
   const [reloadRightContent,setReloadRightContent] = useState(false);
 
+  const [moduleMode,setModuleMode] = useState(false);  //true台账上传 false条文管理
+
+  const [tabKey,setTabKey] = useState<string|number>();  //antd Tab切换
+
+  const [modalVisible,setModalVisible] = useState(false);
+
+  const [uploadFormInitValue, setUploadFormInitValue] = useState<any>();
+
+  const [selectedSelfEvolution,setSelectedSelfEvolution] = useState<{label:string,value:any}>();  //MccsClickableTabs value值
+
+  const [currentSelectedSelefEvolution,setCurrentSelectedSelefEvolution] = useState<{label:string,value:any}>(); //MccsClickableTabs 点击对象
+
   const getArticleTreeData = async (keyword?:string|number) => {
         //获取树数据
         const { list = [] } = await getTreeList(keyword);
         setTreeData(list);
   };
+  
 
   const getTableData = async (params?: any, sorter?: any, filter?: any) => {
     //根据选中树结构的id获取对应的详情
-    if (currentActivedTree) {
-      const resp = await getTreeFileTableData({
+    // console.log({params});
+
+    let specifyId:number|null = null;
+
+    if(params&&params.id){
+      //当存在指定id
+      specifyId = params.id
+    }
+
+    if (currentActivedTree||specifyId) {
+      const resp = await getTreeFileTableData(specifyId?{
+        //传入树结构id指定获取某一节点对应数据
+        ...params,
+        id:specifyId
+      }:{
+        //直接拿树结构id
         ...params,
         id: currentActivedTree ? currentActivedTree.id : 0,
-      });
+      },moduleMode);
   
       if (resp) {
         const {
@@ -90,10 +116,10 @@ const articleManagement = () => {
   }
 
   type FormValueType = {
-    articleType:{label:string,value:string},
+    articleType:{label:string,value:any},
     responsibilityDepartment:{label:string,value:number,[key:string]:any},
     responsibilityUser:{label:string,value:number,[key:string]:any},
-    targetScores:{label:string,value:string},
+    targetScores:{label:string,value:any},
   }
 
   const batchSetting = async (values:FormValueType)=>{
@@ -121,9 +147,7 @@ const articleManagement = () => {
 
   const setArticle = async (values:FormValueType)=>{
     //条文设置
-    //  console.log({values});
-     const {} = values;
-     
+    // console.log({values});
     if(currentActivedTree&&leafData){
       const { id:ruleId } = currentActivedTree;
       const {id} = leafData;
@@ -162,45 +186,168 @@ const articleManagement = () => {
     }
   }
 
+ 
+  
+  const getSelfEvaluationRecordList = async (id:number)=>{
+
+      const resp = await getSelfEvaluation(id);
+
+      if(resp){
+        const {list}:{list:API.GetSelfEvaluationRequestType} = resp;
+        const tempArr = list.map(t =>({
+          evaluation:t.selfEvaluation,
+          details:[{
+            name:t.userName,
+            fileName:t.selfEvaluation,
+            fileUrl:'',
+            historyRecords:[],
+            // recordTypeName:t.selfEvaluation,
+            createTime:t.createDate
+          }]
+        }));
+        setSelfEvaluationRecords(tempArr)
+      }
+    
+  }
+  
+  const uploadFile = async (values:any)=>{
+        console.log({'表单':values});
+      
+        if(leafData){
+          // console.log({'上传表单':values});
+          try{
+            const {files:{fileList=[]},tab} = values;
+            const {id} = leafData;
+            let formData = new FormData();
+            
+            formData.append('file',fileList[0]?.originFileObj);
+            formData.append('id',id.toString());
+        
+            if(JSON.stringify(uploadFormInitValue) != '{}'&&uploadFormInitValue){
+                 //重新上传不允许修改类型
+                 const {tab} = uploadFormInitValue;
+                 formData.append('accountType',tab.label);
+                 formData.append('accountName',tab.value.value);
+
+            }else{
+              formData.append('accountType',tab.label);
+              formData.append('accountName',tab.value.value);
+            }
+            
+            
+            const resp = await uploadFilePost(formData);
+            if(resp){
+                //上传成功,获取最新台账记录
+                getTableData();
+            }
+            setModalVisible(false);
+            //每次提交完清空表单默认值
+            setUploadFormInitValue(undefined);
+          }catch(err){
+              console.log({err});
+          }
+          
+        }
+       
+  }
+
+  const onSelfEvolutionTabChange = (value:{label:string,value:any})=>{
+    //自评tab切换回调
+    // console.log({value});
+    value&&setCurrentSelectedSelefEvolution(value);
+    value&&setSelectedSelfEvolution(value);
+  }
+
+  const commitSelfEvolution = async ()=>{
+    //提交自评
+    if(leafData&&currentSelectedSelefEvolution){
+      //存在详情信息,且已选择评分
+      const {id} = leafData;
+      let _userData = localStorage.getItem('userData');
+      if(_userData){
+        let userData:{name:string,userId:number} = JSON.parse(_userData)
+        const params = {
+          id:Number(id),
+          selfEvaluation:`${currentSelectedSelefEvolution?currentSelectedSelefEvolution.value:'null'}`,
+          userId:userData?.userId,
+          userName:userData?.name,
+        }
+         const resp = await selfEvolutionCommit(params);
+         if(resp&&currentActivedTree){
+           //刷新自评记录
+          getSelfEvaluationRecordList(Number(currentActivedTree.id));
+          setSelectedSelfEvolution({label:'null',value:'null'});  //清空选中项
+          setCurrentSelectedSelefEvolution(undefined);
+         }
+      }  
+    }else{
+      notification['info']({
+        message: '请选择评分!',
+      });
+    }
+  }
+
+  const delHistoryRecordHandle = async (historyRecords:MccsRecordList.historyRecordsItem)=>{
+    //删除台账记录
+    const resp = await delHistoryRecods(historyRecords.id);
+    if(resp){
+      getTableData();
+    }
+
+  } 
+
+  const getScoreList = async ()=>{
+        //条文评级
+        const data =  await getScoreLevelData();
+        const tempArr = data.map((t:any)=>({label:t.levelNumber,value:t.levelNumber}));
+        return Promise.resolve(tempArr);
+  }
+
+  const accreditationGroupType = async ()=>{
+        //获取条文组别
+        const data =  await getAccreditationTypeData();
+        const tempArr = data.map((t:any)=>({label:t.categoryType,value:t.categoryType}));
+        return Promise.resolve(tempArr);
+  }
+
+  const getUploadLedgerType = async ()=>{
+        //台账类型
+        const data = await getUploadLedgerSelectableType();
+        if(data){
+          const tempArr = data.map((t:{levelNumber:string,generalNameList:string[]})=>{
+            const tempList = t.generalNameList.map(a=>{
+                   return {
+                       label:a,
+                       value:a
+                   }
+            });
+            return {label:t.levelNumber,list:tempList}
+          });
+          return Promise.resolve(tempArr);
+        }
+  }
+
+
   useEffect(() => {
     if (currentActivedTree) {
       const { isLeaf} = currentActivedTree;
       setIsLeaf(isLeaf);
       getTableData();
+      if(isLeaf){
+        getScoreList().then(data=>{
+          setTargetScores(data);
+        });
+        accreditationGroupType().then(data=>{
+          setRuleTypes(data);
+        });
+      }
     }
-    setTargetScores([
-        {
-            label:'A',
-            value:'A'
-        },
-        {
-            label:'B',
-            value:'B'
-        },
-        {
-          label:'C',
-          value:'C'
-        }
-    ]);
-    setRuleTypes([
-        {
-            label:'A',
-            value:'A'
-        },
-        {
-            label:'B',
-            value:'B'
-        },
-        {
-            label:'C',
-            value:'C'
-        }
-    ]);
+  
   }, [currentActivedTree]);
 
   useEffect(() => {
     if (leafData) {
-      const { systemEvaluation, targetEvaluation, selfEvaluation, siteEvaluation,records=[] } = leafData;
+      const { systemEvaluation, targetEvaluation, selfEvaluation, siteEvaluation,records=[],accountRecords=[] } = leafData;
       const tempScoreList = [
         {
           label: '自评',
@@ -220,21 +367,56 @@ const articleManagement = () => {
         },
       ];
       // console.log({tempScoreList});
-      
-      const tempRecords = records.map((item:API.RecordsItemType)=>{
-        
-         const tempArr = item.details.map(val=>({
-          name:val.userName,
-          fileName:val.fileName,
-          fileUrl:val.fileUrl,
-          createTime:val.createTime,
-          recordTypeName:val.recordTypeName,
-          historyRecords:[]
-         }))
-         return {
-          evaluation:item.evaluation,
-          details:tempArr
+      let recordsArray:API.RecordsItemType[]=[];
+
+      records&&records.length>0&&(recordsArray=records);  //条文管理
+      accountRecords&&accountRecords.length>0&&(recordsArray=accountRecords); //台账上传
+      // console.log({recordsArray,accountRecords,records});
+      const tempRecords = recordsArray.map((item)=>{
+
+         if(item.details){
+           
+          const tempArr:MccsRecordList.MccsRecordListItemInnerDetail[]  = item.details.map(val=>({
+            name:val.userName,
+            fileName:val.fileName,
+            fileUrl:val.fileUrl,
+            createTime:val.createTime,
+            recordTypeName:val.recordTypeName,
+             //条文管理无台账记录
+             historyRecords:[]
+           }))
+           return {
+            evaluation:item.evaluation,
+            details:tempArr
+           }
+         }
+
+         if(item.records){
+          const tempArr:MccsRecordList.MccsRecordListItemInnerDetail[] = item.records.map(val=>({
+
+            name:val.uploadUserName,
+            fileName:val.fileName,
+            fileUrl:val.fileUrl,
+            createTime:val.uploadTime,
+            recordTypeName:val.accountName,
+            historyRecords:val.historyVersionVOList?val.historyVersionVOList.map(t=>({
+              versionName:t.versionName,name:val.uploadUserName,time:val.uploadTime,id:t.id
+            })):[]
+            
+           }))
+
+           return {
+            evaluation:item.evaluation,
+            details:tempArr
+           }
+          
          }
+         
+         //后台接口字段缺失,保证组件正常运行
+         return {
+          evaluation:'null',
+          details:[]
+        };
       });
       
       setScoreList(tempScoreList);
@@ -242,9 +424,19 @@ const articleManagement = () => {
     }
   }, [leafData]);
 
-  useEffect(() => {
-    getArticleTreeData();
-  }, []);
+  useEffect(()=>{
+       //tab切换时
+       //tab切换时重置
+       setSelectedSelfEvolution({label:'',value:''}); 
+       setCurrentSelectedSelefEvolution(undefined); 
+       if(tabKey==2){
+             //切换为自评记录
+             getSelfEvaluationRecordList(Number(currentActivedTree?.id));  //获取自评记录列表
+
+       }
+  },[tabKey]);
+
+  
 
   return {
     isLeaf,
@@ -255,6 +447,7 @@ const articleManagement = () => {
     currentActivedTree,
     setCurrentActivedTree,
     scoreList, //评分
+    records,//台账记录
     getDepartmentRequest,
     departmentManagers,
     getDepartment,
@@ -268,7 +461,23 @@ const articleManagement = () => {
     drawerVisible,
     setDrawerVisible,
     setSelectedRowKeys,
-    reloadRightContent
+    reloadRightContent,
+    setReloadRightContent,
+    setModuleMode,
+    moduleMode,
+    setTabKey,
+    selfEvaluationRecords,
+    modalVisible,
+    setModalVisible,
+    uploadFile,
+    uploadFormInitValue,
+    setUploadFormInitValue,
+    onSelfEvolutionTabChange,
+    commitSelfEvolution,
+    selectedSelfEvolution,
+    getSelfEvaluationRecordList,
+    delHistoryRecordHandle,
+    getUploadLedgerType
   };
 };
 

+ 69 - 8
src/pages/GradeHospitalAccreditation/articleManagement/server.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 10:22:20
- * @LastEditTime: 2021-09-16 17:08:15
+ * @LastEditTime: 2021-09-29 16:28:52
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/server.ts
@@ -16,13 +16,21 @@ import { request } from 'umi';
 
 
 //获取条文表格数据
-export const getTreeFileTableData  = async (query:{id:string|number,keyword?:string|number})=>{
-  
-    return request('/api/pfm/reviewArticle/list', {
-        method: 'GET',
-        params:{...query}
-    });
-
+export const getTreeFileTableData  = async (query:{id:string|number,keyword?:string|number},mode?:boolean)=>{
+    
+    if(!mode){
+        //条文
+        return request('/api/pfm/reviewArticle/list', {
+            method: 'GET',
+            params:{...query}
+        });
+    }else {
+        //台账
+        return request('/api/pfm/recordUpload/list', {
+            method: 'GET',
+            params:{...query}
+        });
+    }
 }
 
 //获取单位列表
@@ -57,6 +65,59 @@ export const batchSettingArticle  = async (data:API.batchSettingArticleType)=>{
 
 }
 
+//获取自评记录
+
+export const getSelfEvaluation  = async (ruleId:string|number)=>{
+  
+    return request('/api/pfm/pfmarticlehistory/getSelfEvaluation', {
+        method: 'GET',
+        params:{ruleId}
+    });
+
+}
+
+//上传台账
+
+
+export const uploadFilePost  = async (uploadData:any)=>{
+    
+    return request('/api/pfm/recordUpload/setRecordFile', {
+        method: 'POST',
+        data:uploadData
+    });
+
+}
+
+// 自评
+
+export const selfEvolutionCommit  = async (data:API.SelfEvolutionCommitType)=>{
+    
+    return request('/api/pfm/recordUpload/setSelfEvaluationResult', {
+        method: 'POST',
+        data:data
+    });
+
+}
+
+// 删除台账历史记录
+
+export const delHistoryRecods  = async (id:number)=>{
+    
+    return request('/api/pfm/recordUpload/deleteHistory', {
+        method: 'POST',
+        params:{id}
+    });
+
+}
+
+//获取可选台账类型
+export const getUploadLedgerSelectableType = async ()=>{
+    return request('/api/pfm/sysgeneralconfig/getAccountConfigByType', {
+        method: 'GET',
+    });
+}
+
+
 
 
 

+ 100 - 50
src/pages/GradeHospitalAccreditation/articleManagement/typings.d.ts

@@ -1,62 +1,112 @@
 /*
  * @Author: your name
  * @Date: 2021-09-14 10:22:42
- * @LastEditTime: 2021-09-16 17:17:48
+ * @LastEditTime: 2021-09-28 11:45:02
  * @LastEditors: Please set LastEditors
  * @Description: In User Settings Edit
  * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/typings.d.ts
  */
 
+declare namespace API {
+  type RecordsItemType = {
+    evaluation: string;
+    details?:
+      | {
+          userName: string;
+          fileName: string;
+          fileUrl: string;
+          createTime: string;
+          recordTypeName: string;
+        }[]
+      | [];
+    records?:
+      | {
+          existHistory: boolean;
+          uploadUserName: string;
+          fileName: string;
+          fileUrl: string;
+          uploadTime: string;
+          accountName: string;
+          historyVersionVOList: {
+            versionName: string;
+            accountName: string;
+            uploadUserName: string;
+            fileName: string;
+            fileUrl: string;
+            uploadTime: string;
+            id:number
+          }[];
+        }[]
+      | [];
+  };
 
+  type LeafDataType = {
+    id: number;
+    numStr: string;
+    name: string;
+    accountType: string;
+    responsibilityDepartmentName:string;
+    responsibilityUserName: string;
+    responsibilityDepartmentId:number,
+    responsibilityUserId:number,
+    selfEvaluation: string;
+    targetEvaluation: string;
+    systemEvaluation: string;
+    siteEvaluation: string;
+    records?: RecordsItemType[];
+    accountRecords?: RecordsItemType[];
+  };
 
+  type settingArticlePostDataType = {
+    id: number; // maybe 0
+    ruleId: number;
+    responsibilityDepartmentId: number;
+    responsibilityDepartmentName: string;
+    responsibilityUserId: number;
+    responsibilityUserName: string;
+    targetEvaluation: string;
+    articleType: string;
+  };
+
+  type tableDataItemType = {
+    id: number;
+    numStr: string;
+    name: string;
+    accountType: string;
+    responsibilityDepartmentName: string;
+    responsibilityUserName: string;
+    selfEvaluation: string;
+    targetEvaluation: string;
+    systemEvaluation: string;
+    siteEvaluation: string;
+  };
+
+  type batchSettingArticleType = {
+    ruleIds: number[] | string[] | [];
+    responsibilityDepartmentId: number;
+    responsibilityDepartmentName: string;
+    responsibilityUserId: number;
+    responsibilityUserName: string;
+    targetEvaluation: string;
+    articleType: string;
+  };
+
+  type GetSelfEvaluationRequestType = {
+    //获取自评记录
+    id: number;
+    selfEvaluation: string;
+    userName: string;
+    createTime: number;
+    createDate: string;
+  }[];
+
+  type SelfEvolutionCommitType = {
+    id:number,
+    selfEvaluation:string,
+    userId:number,
+    userName:string
+  }
+
+}
 
-declare namespace API {
 
-     type RecordsItemType = {
-      evaluation:string,
-      details:{
-         userName:string,
-         fileName:string,
-         fileUrl:string,
-         createTime:string,
-         recordTypeName:string
-      }[]
-     }
-
-     type LeafDataType = {
-        id:number,	
-        numStr:string,	
-        name:string,	
-        articleType:string,
-        responsibilityDepartmentName:number,	
-        responsibilityUserName:string,
-        selfEvaluation:string,	
-        targetEvaluation:string,
-        systemEvaluation:string,
-        siteEvaluation:string,
-        records?:RecordsItemType[]
-     }
-
-
-     type settingArticlePostDataType = {
-      id:number,  // maybe 0
-      ruleId:number,
-      responsibilityDepartmentId:number,
-      responsibilityDepartmentName:string,
-      responsibilityUserId:number,
-      responsibilityUserName:string,
-      targetEvaluation:string,
-      articleType:string
-     }
-
-     type batchSettingArticleType = {
-      ruleIds:number[]|string[]|[],
-      responsibilityDepartmentId:number,
-      responsibilityDepartmentName:string,
-      responsibilityUserId:number,
-      responsibilityUserName:string,
-      targetEvaluation:string,
-      articleType:string
-     }
-
-}

+ 61 - 0
src/pages/GradeHospitalAccreditation/ledgerUpload/index.less

@@ -0,0 +1,61 @@
+.leafContent {
+  .leafContentTitle {
+    font-size: 16px;
+    font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+    font-weight: bold;
+    color: #292C33;
+    line-height: 24px;
+    overflow: hidden; //超出的文本隐藏
+    text-overflow: ellipsis; //溢出用省略号显示
+    white-space: nowrap; //溢出不换行
+    margin-bottom: 16px;
+  }
+
+  .peopleGroup {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
+    margin-bottom: 24px;
+
+    span {
+      font-size: 14px;
+      font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+      font-weight: 400;
+      color: #292C33;
+      line-height: 21px;
+
+      &:nth-child(2n) {
+        margin-right: 40px;
+      }
+    }
+  }
+
+  .articleSetBtn {
+    height: 50px;
+    text-align: center;
+    line-height: 50px;
+    background: #FFFFFF;
+    border-radius: 25px;
+    border: 1px dashed #DADEE6;
+    margin-top: 10px;
+    margin-bottom: 40px;
+
+    span {
+      font-size: 16px;
+      font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+      font-weight: 400;
+      cursor: pointer;
+      color: @primary-color;
+    }
+  }
+}
+
+
+.formItemTitle {
+    font-size: 16px;
+    font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+    font-weight: 400;
+    color: #7A8599;
+    margin-bottom:16px;
+  }

+ 287 - 0
src/pages/GradeHospitalAccreditation/ledgerUpload/index.tsx

@@ -0,0 +1,287 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-14 10:22:09
+ * @LastEditTime: 2021-09-29 17:12:13
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/index.tsx
+ */
+
+
+import React, { useEffect,useState } from 'react'
+import {useModel} from 'umi';
+import { Form,Tabs,Button } from 'antd'
+import {
+    ProFormText,
+    ProFormSelect,
+    ProFormDependency,
+    ProFormDateRangePicker,
+} from '@ant-design/pro-form';
+
+import ArticleManagementCopy from '@/pages/GradeHospitalAccreditation/articleManagement/index';
+import MccsDrawerForm from '@/components/MccsDrawerForm/index';
+import './index.less';
+import MccsScoreBanner from '@/components/MccsScoreBanner';
+import MccsRecordList from '@/components/MccsRecordList/index';
+import MccsClickableTabs from '@/components/MccsClickableTabs/index';
+
+
+type LedgerUploadPropsType = {
+
+}
+
+const { TabPane } = Tabs;
+
+//条文管理
+const LedgerUpload: React.FC<LedgerUploadPropsType> = (props) => {
+
+    const columns = [
+        {
+            key: 'articleType',
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+    
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                    
+                        <ProFormSelect
+                            width='sm'
+                            options={[
+                                { label: '全部', value: 'all' },
+                                { label: '未解决', value: 'open' },
+                                { label: '已解决', value: 'closed' },
+                                { label: '解决中', value: 'processing' },
+                            ]}
+                            placeholder="台账状态"
+                        />
+                   
+                )
+            },
+        },
+        {
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+    
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                   
+                        <ProFormDateRangePicker name='date'  placeholder={['开始时间','结束时间']} />
+                  
+                )
+            },
+        },
+        {
+            key: 'keyword',
+            hideInTable: true,
+            renderFormItem: (item: any, { type }: any, form: any) => {
+    
+                if (type === 'form') {
+                    return null;
+                }
+                return (
+                    <Form.Item name='keyword'>
+                        <ProFormText placeholder='条文/条款' />
+                    </Form.Item>
+                )
+            },
+        },
+        {
+            title: '条款',
+            key: 'numStr',
+            dataIndex: 'numStr',
+            hideInSearch: true,
+    
+        },
+        {
+            title: '条文',
+            dataIndex: 'name',
+            hideInSearch: true,
+            width: '35%'
+        },
+        {
+            title: '负责单位',
+            dataIndex: 'responsibilityDepartmentName',
+            hideInSearch: true,
+        },
+        {
+            title: '负责人',
+            dataIndex: 'responsibilityUserName',
+            hideInSearch: true,
+        },
+        {
+            title: '自评',
+            hideInSearch: true,
+            dataIndex: 'selfEvaluation',
+        },
+        {
+            title: '现场查核',
+            hideInSearch: true,
+            dataIndex: 'siteEvaluation',
+        },
+        {
+            title: '目标',
+            dataIndex: 'targetEvaluation',
+            hideInSearch: true,
+        },
+        {
+            title: '系统评分',
+            dataIndex: 'systemEvaluation',
+            hideInSearch: true,
+        },
+        {
+            title: '操作',
+            width: 100,
+            valueType: 'option',
+            render: (_:any, record:any) =>{
+                   
+                   return [<a key="1" onClick={()=>openDrawerHandle(record)}>详情</a>, <a key="2" onClick={()=>del(record)}>删除</a>]
+            },
+        },
+    ]
+
+    const { articleManagement,ledgerUpload } = useModel('allModels',model=>{
+            return {articleManagement:model.articleManagement,ledgerUpload:model.ledgerUpload};
+    });
+
+    const {
+ 
+        currentActivedTree,
+        ...restArticleManagementModelData
+    } = articleManagement;
+    
+    const {...restLedgerUploadModelData} = ledgerUpload;
+
+    const [tabKey,setTabKey] = useState<string|number>();  //antd Tab切换
+
+
+    const openDrawerHandle = (record:any)=>{
+        // console.log({record});
+        restLedgerUploadModelData.setCurrentRecord(record)
+        restLedgerUploadModelData.setDrawerVisible(true);
+        restArticleManagementModelData.getTableData({id:record.id});
+    }
+
+    const del = (record:any)=>{
+
+        const {id} = record;
+        restLedgerUploadModelData.delRuleHandle(id);
+        restArticleManagementModelData.getArticleTreeData();  //刷新树结构
+        restArticleManagementModelData.setReloadRightContent(true);  //刷新表格数据
+    }
+
+    const onVisibleChangeHandle = (visible: boolean) => {
+        restLedgerUploadModelData.setDrawerVisible(visible);
+    }
+
+    const upLoadFileHandle = (formInitData?:any) => {
+        //因为modalForm开启了request+params获取表单默认值,
+        //所以必须先设置默认值才能开启弹窗
+        if(formInitData){
+            const { fileUrl, recordTypeName, fileName } = formInitData;
+            restArticleManagementModelData.setUploadFormInitValue({
+                tab: recordTypeName,
+                files: [{
+                    uid: new Date().getTime(),
+                    name: fileName,
+                    status: 'done',
+                    url: fileUrl
+                }]
+            });
+        }else {
+            restArticleManagementModelData.setUploadFormInitValue({})
+        }
+        restArticleManagementModelData.setModalVisible(true);
+    }
+
+    const actionNodeFunc = (data: any) => {
+        //渲染记录列表操作按钮
+        // console.log({ data });
+        const reupload = () => {
+            
+            upLoadFileHandle(data);
+        }
+
+        return <a onClick={reupload}>重新上传</a>
+    }
+
+    
+
+    useEffect(()=>{
+        //tab切换时
+        //tab切换时重置
+        // restArticleManagementModelData.setSelectedSelfEvolution(['null']); 
+        // restArticleManagementModelData.setCurrentSelectedSelefEvolution(undefined); 
+        if(tabKey==2){
+              //切换为自评记录
+              if(restLedgerUploadModelData.currentRecord){
+                restLedgerUploadModelData.getSelfEvaluationRecordList(restLedgerUploadModelData.currentRecord.id);  //获取自评记录列表
+              }
+
+        }
+    },[tabKey]);
+    
+    return (
+        <React.Fragment>
+            <ArticleManagementCopy 
+                columnsFromProps={columns}
+                isModeTwo={true}
+            />
+
+            
+            <MccsDrawerForm 
+               title={restLedgerUploadModelData.currentRecord?.name}
+               visible = {restLedgerUploadModelData.drawerVisible}
+               onVisibleChange={onVisibleChangeHandle}
+            >
+                <div className='leafContent'>
+                
+                                <div className='peopleGroup'>
+                                    <span>条文组别:</span>
+                                    <span>{restLedgerUploadModelData.currentRecord?.accountType}</span>
+                                    <span>负责单位:</span>
+                                    <span>{restLedgerUploadModelData.currentRecord?.responsibilityDepartmentName}</span>
+                                    <span>负责人:</span>
+                                    <span>{restLedgerUploadModelData.currentRecord?.responsibilityUserName}</span>
+                                </div>
+                                <MccsScoreBanner list={restLedgerUploadModelData.scoreList} />
+                       
+                                <div style={{ marginTop: 5 }}>
+                                            <Tabs defaultActiveKey="1" centered size='large' onChange={(key) => setTabKey(key)}>
+                                                <TabPane tab="台账记录" key="1">
+                                                    <div className='articleSetBtn'>
+                                                        <span onClick={()=>upLoadFileHandle()}>上传文件</span>
+                                                    </div>
+                                                    <MccsRecordList
+                                                        title='台账记录'
+                                                        list={restArticleManagementModelData.records}
+                                                        actionNode={(data) => actionNodeFunc(data)}
+                                                    />
+                                                </TabPane>
+                                                <TabPane tab="自评结果" key="2">
+                                                    <div className='selfEvolutionArea'>
+                                                        <div className='selfEvolutionTitle'>开始自评</div>
+                                                        <MccsClickableTabs
+                                                            onChange={(value:{label:string,value:any})=>restLedgerUploadModelData.onSelfEvolutionTabChange(value)}
+                                                            data={restLedgerUploadModelData.targetScores}
+                                                            value={restLedgerUploadModelData.selectedSelfEvolution}
+                                                        />
+                                                        <Button onClick={()=>restLedgerUploadModelData.commitSelfEvolution()}>提交自评</Button>
+                                                    </div>
+                                                    <MccsRecordList
+                                                        title='自评记录'
+                                                        list={restLedgerUploadModelData.selfEvaluationRecords}
+                                                    />
+                                                </TabPane>
+                                            </Tabs>
+                                </div>
+                </div>
+            </MccsDrawerForm>
+        </React.Fragment>
+    )
+}
+
+export default LedgerUpload

+ 204 - 0
src/pages/GradeHospitalAccreditation/ledgerUpload/model.ts

@@ -0,0 +1,204 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-14 10:46:45
+ * @LastEditTime: 2021-09-29 17:13:09
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/model.ts
+ */
+
+import { useState, useEffect } from 'react';
+import {
+  getTreeFileTableData,
+  getSelfEvaluation,
+  selfEvolutionCommit
+} from '@/pages/GradeHospitalAccreditation/articleManagement/server';
+import { delDetailRule } from '@/pages/GradeHospitalAccreditation/accreditationDetail/service';
+
+//ledgerUpload
+const ledgerUpload = () => {
+  const [drawerVisible, setDrawerVisible] = useState(false);
+  const [scoreList, setScoreList] = useState<any[]>([]);
+  const [records, setRecords] = useState<MccsRecordList.MccsRecordListType>();
+  const [currentRecord, setCurrentRecord] = useState<API.tableDataItemType>();
+  const [currentLeafData, setCurrentLeafData] = useState<API.LeafDataType>();
+  const [selfEvaluationRecords, setSelfEvaluationRecords] = useState<MccsRecordList.MccsRecordListType>([]); //自评记录
+  // const [drawerFormType, setDrawerFormType] = useState<'ARTICLE_SET' | 'BATCHSETTING'>(  'ARTICLE_SET');
+
+  const [targetScores,setTargetScores] = useState<MccsClickableTabs.TabType[]>([]);
+
+  const [selectedSelfEvolution,setSelectedSelfEvolution] = useState<{label:string,value:any}>();  //MccsClickableTabs value值
+
+  const [currentSelectedSelefEvolution,setCurrentSelectedSelefEvolution] = useState<{label:string,value:any}>(); //MccsClickableTabs 点击对象
+
+  const getTableData = async () => {
+    //根据选中表格的id获取对应的详情
+    if (currentRecord) {
+      const resp = await getTreeFileTableData({
+        id: currentRecord ? currentRecord.id : 0,
+      });
+
+      if (resp) {
+        const { leafData, isLeaf } = resp;
+
+        if (isLeaf && leafData) {
+          setCurrentLeafData(leafData);
+        }
+      }
+      return [];
+    }
+  };
+
+  const delRuleHandle = async (id: number) => {
+    await delDetailRule(id);
+  };
+
+  const getSelfEvaluationRecordList = async (id: number) => {
+    //获取自评记录(无法从accreditationDetail迁移)
+    const resp = await getSelfEvaluation(id);
+
+    if (resp) {
+      const { list }: { list: API.GetSelfEvaluationRequestType } = resp;
+      const tempArr = list.map((t) => ({
+        evaluation: t.selfEvaluation,
+        details: [
+          {
+            name: t.userName,
+            fileName: t.selfEvaluation,
+            fileUrl: '',
+            historyRecords: [],
+            // recordTypeName: t.selfEvaluation,
+            createTime: t.createDate,
+          },
+        ],
+      }));
+      setSelfEvaluationRecords(tempArr);
+    }
+  };
+
+  const commitSelfEvolution = async ()=>{
+    //提交自评
+    if(currentLeafData&&currentSelectedSelefEvolution){
+      //存在详情信息,且已选择评分
+      const {id} = currentLeafData;
+      let _userData = localStorage.getItem('userData');
+      if(_userData){
+        let userData:{name:string,userId:number} = JSON.parse(_userData)
+        const params = {
+          id:Number(id),
+          selfEvaluation:`${currentSelectedSelefEvolution?currentSelectedSelefEvolution:'null'}`,
+          userId:userData?.userId,
+          userName:userData?.name
+        }
+         const resp = await selfEvolutionCommit(params);
+         if(resp&&currentRecord){
+           //刷新自评记录
+          getSelfEvaluationRecordList(Number(currentRecord.id));
+          setSelectedSelfEvolution(undefined);  //清空选中项
+          setCurrentSelectedSelefEvolution(undefined);
+         }
+      }  
+    }else{
+      // notification['info']({
+      //   message: '请选择评分!',
+      // });
+    }
+  }
+
+  const onSelfEvolutionTabChange = (value:{label:string,value:any})=>{
+    //自评tab切换回调
+    value&&setCurrentSelectedSelefEvolution(value);
+    value&&setSelectedSelfEvolution(value);
+  }
+
+  useEffect(() => {
+    //点击时获取对应详情
+    getTableData();
+    setTargetScores([
+      {
+          label:'A',
+          value:'A'
+      },
+      {
+          label:'B',
+          value:'B'
+      },
+      {
+        label:'C',
+        value:'C'
+      }
+  ]);
+  }, [currentRecord]);
+
+  useEffect(() => {
+    if (currentLeafData) {
+      const {
+        systemEvaluation,
+        targetEvaluation,
+        selfEvaluation,
+        siteEvaluation,
+        records = [],
+      } = currentLeafData;
+      const tempScoreList = [
+        {
+          label: '自评',
+          value: selfEvaluation ? selfEvaluation : '-',
+        },
+        {
+          label: '现场查核',
+          value: siteEvaluation ? siteEvaluation : '-',
+        },
+        {
+          label: '目标',
+          value: targetEvaluation ? targetEvaluation : '-',
+        },
+        {
+          label: '系统评分',
+          value: systemEvaluation ? systemEvaluation : '-',
+        },
+      ];
+      // console.log({tempScoreList});
+
+      const tempRecords = records.map((item: API.RecordsItemType) => {
+        if (item.details) {
+          const tempArr = item.details.map((val) => ({
+            name: val.userName,
+            fileName: val.fileName,
+            fileUrl: val.fileUrl,
+            createTime: val.createTime,
+            recordTypeName: val.recordTypeName,
+            historyRecords: [],
+          }));
+          return {
+            evaluation: item.evaluation,
+            details: tempArr,
+          };
+        }
+        return { evaluation: 'null', details: [] };
+      });
+
+      setScoreList(tempScoreList);
+      setRecords(tempRecords);
+    }
+  }, [currentLeafData]);
+
+  return {
+    drawerVisible,
+    currentRecord,
+    setCurrentRecord,
+    setDrawerVisible,
+    scoreList,
+    records,
+    delRuleHandle,
+    currentLeafData,
+    getSelfEvaluationRecordList,
+    selfEvaluationRecords,
+    setCurrentSelectedSelefEvolution,
+    onSelfEvolutionTabChange,
+    commitSelfEvolution,
+    selectedSelfEvolution,
+    targetScores
+  };
+};
+
+export default ledgerUpload;

+ 64 - 0
src/pages/GradeHospitalAccreditation/ledgerUpload/server.ts

@@ -0,0 +1,64 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-14 10:22:20
+ * @LastEditTime: 2021-09-18 16:44:07
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/server.ts
+ */
+
+
+
+import { request } from 'umi';
+
+
+
+
+
+//获取条文表格数据
+export const getTreeFileTableData  = async (query:{id:string|number,keyword?:string|number})=>{
+  
+    return request('/api/pfm/reviewArticle/list', {
+        method: 'GET',
+        params:{...query}
+    });
+
+}
+
+//获取单位列表
+export const getDepartmentList  = async (query?:{responsibilityDepartmentId?:number,responsibilityUserId?:number})=>{
+  
+    return request('/api/pfm/sysdepartment/getSysDepartmentList', {
+        method: 'GET',
+        params:{...query}
+    });
+
+}
+
+//条文设置
+
+export const settingArticle  = async (data:API.settingArticlePostDataType)=>{
+  
+    return request('/api/pfm/reviewArticle/setArticle', {
+        method: 'POST',
+        data:{...data}
+    });
+
+}
+
+//条文批量设置
+
+export const batchSettingArticle  = async (data:API.batchSettingArticleType)=>{
+  
+    return request('/api/pfm/reviewArticle/setTargetEvaluation', {
+        method: 'POST',
+        data:{...data}
+    });
+
+}
+
+
+
+
+
+

+ 62 - 0
src/pages/GradeHospitalAccreditation/ledgerUpload/typings.d.ts

@@ -0,0 +1,62 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-14 10:22:42
+ * @LastEditTime: 2021-09-28 11:43:14
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/GradeHospitalAccreditation/articleManagement/typings.d.ts
+ */
+
+
+
+
+declare namespace API {
+
+     type RecordsItemType = {
+      evaluation:string,
+      details:{
+         userName:string,
+         fileName:string,
+         fileUrl:string,
+         createTime:string,
+         recordTypeName:string
+      }[]
+     }
+
+     type LeafDataType = {
+        id:number,	
+        numStr:string,	
+        name:string,	
+        accountType:string,
+        responsibilityDepartmentName:number,	
+        responsibilityUserName:string,
+        selfEvaluation:string,	
+        targetEvaluation:string,
+        systemEvaluation:string,
+        siteEvaluation:string,
+        records?:RecordsItemType[]
+     }
+
+
+     type settingArticlePostDataType = {
+      id:number,  // maybe 0
+      ruleId:number,
+      responsibilityDepartmentId:number,
+      responsibilityDepartmentName:string,
+      responsibilityUserId:number,
+      responsibilityUserName:string,
+      targetEvaluation:string,
+      articleType:string
+     }
+
+     type batchSettingArticleType = {
+      ruleIds:number[]|string[]|[],
+      responsibilityDepartmentId:number,
+      responsibilityDepartmentName:string,
+      responsibilityUserId:number,
+      responsibilityUserName:string,
+      targetEvaluation:string,
+      articleType:string
+     }
+
+}

+ 6 - 0
src/pages/KeepImprove/departmentIssueRank/index.less

@@ -0,0 +1,6 @@
+
+
+
+#reportFrame {
+    border: none;
+}

+ 29 - 0
src/pages/KeepImprove/departmentIssueRank/index.tsx

@@ -0,0 +1,29 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-28 13:57:19
+ * @LastEditTime: 2021-09-28 16:33:57
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/questionGatherAndRevise/index.tsx
+ */
+
+
+import React from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+
+import './index.less';
+
+
+type QuestionGatherAndReviseProps = {}
+
+const QuestionGatherAndRevise:React.FC<QuestionGatherAndReviseProps> = ()=>{
+    return (
+        <MccsPageContainer>
+            <iframe  id="reportFrame" src="http://8.136.135.180:8081/webroot/ReportServer?formlet=PFM/test/单位问题排名.frm" width="100%" height="800px">
+            </iframe>
+        </MccsPageContainer>
+    )
+}
+
+export default QuestionGatherAndRevise
+

+ 6 - 0
src/pages/KeepImprove/departmentScoreRank/index.less

@@ -0,0 +1,6 @@
+
+
+
+#reportFrame {
+    border: none;
+}

+ 29 - 0
src/pages/KeepImprove/departmentScoreRank/index.tsx

@@ -0,0 +1,29 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-28 13:57:19
+ * @LastEditTime: 2021-09-28 16:41:55
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/questionGatherAndRevise/index.tsx
+ */
+
+
+import React from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+
+import './index.less';
+
+
+type QuestionGatherAndReviseProps = {}
+
+const QuestionGatherAndRevise:React.FC<QuestionGatherAndReviseProps> = ()=>{
+    return (
+        <MccsPageContainer>
+            <iframe  id="reportFrame" src="http://8.136.135.180:8081/webroot/ReportServer?formlet=PFM/test/单位得分排名.frm" width="100%" height="800px">
+            </iframe>
+        </MccsPageContainer>
+    )
+}
+
+export default QuestionGatherAndRevise
+

+ 79 - 0
src/pages/KeepImprove/qualityRating/index.less

@@ -0,0 +1,79 @@
+.content {
+  padding: 0 16px;
+  padding-top: 32px;
+  padding-bottom: 30px;
+  background: #FFFFFF;
+  border-radius: 2px;
+   
+  .blockTitle {
+    font-size: 16px;
+    font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+    font-weight: bold;
+    color: #292C33;
+    margin-bottom: 24px;
+  }
+
+  .tableWrap {
+     margin-bottom: 32px;
+    .columnsWrap {
+      display: flex;
+      width: 100%;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: center;
+      border-bottom: 2px solid white;
+      .list {
+        width: calc(100%/6);
+        height: 48px;
+        line-height: 48px;
+        text-align: center;
+        background: #E9EFF7;
+        font-size: 14px;
+        font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+        font-weight: bold;
+        color: #292C33;
+        border-right: 2px solid white;
+        
+        &:last-child {
+          border: none;
+        }
+      }
+    }
+
+    .row {
+       .rowList {
+            display: flex;
+            width: 100%;
+            flex-direction: row;
+            justify-content: flex-start;
+            align-items: center;
+            border-bottom: 2px solid white;
+
+            .list {
+                width: calc(100%/6);
+                height: 48px;
+                line-height: 48px;
+                text-align: center;
+                background: #F5F8FC;
+                font-size: 14px;
+                font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+                font-weight: bold;
+                color: #292C33;
+                border-right: 2px solid white;
+
+                &:first-child {
+                    background: #E9EFF7;
+                }
+                &:last-child {
+                   border: none;
+                }
+            } 
+
+            &:last-child {
+                border-bottom: none;
+            }
+       }
+      
+    }
+  }
+}

+ 289 - 0
src/pages/KeepImprove/qualityRating/index.tsx

@@ -0,0 +1,289 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-26 16:56:46
+ * @LastEditTime: 2021-09-29 16:15:46
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/ qualityRating/index.tsx
+ */
+
+
+import React, { useState, useEffect } from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+import { Column, DualAxes } from '@ant-design/charts';
+
+import { getTableData, getColumnData } from './serve';
+import './index.less';
+
+
+type QualityRatingType = {
+
+}
+
+type TableDataItemType = {
+    typeLevel: string,
+    requirements: string,
+    site: string,
+    target: string,
+    self: string,
+    system: string
+}
+
+
+const setColor = (type:string) => {
+    switch (type) {
+        case 'A':
+            return '#69D1CC';
+            break
+        case 'B':
+            return '#80ABFF';
+            break
+        case 'C':
+            return '#FFC080';
+            break
+        case 'D':
+            return '#3377FF';
+            break
+        case 'E':
+            return '#690';
+            break
+    }
+}
+
+
+const QualityRating: React.FC<QualityRatingType> = (props) => {
+
+
+    const [tableData, setTableData] = useState<TableDataItemType[]>([]);
+    const [mapData, setMapData] = useState<any>([]);
+    const [lineData, setLineData] = useState<any>([]);
+
+    const getTableDataFunc = async () => {
+        const resp = await getTableData();
+        if (resp) {
+            setTableData(resp);
+            const lineArr = resp.map((t: any) => {
+                //设置辅助线
+                return {
+                    type: 'line',
+                    start: ['min', Number(t.requirements.replace(/[^0-9]/ig, ""))],
+                    end: ['max', Number(t.requirements.replace(/[^0-9]/ig, ""))],
+                    text: {
+                        content: `要求值${Number(t.requirements.replace(/[^0-9]/ig, ""))}%`,
+                        position: 'right',
+                        offsetY: 7,
+                        offsetX:70,
+                        style: { textAlign: 'right', fill:setColor(t.typeLevel)},
+
+                    },
+                    style: {
+                        lineDash: [5, 5],
+                        stroke:setColor(t.typeLevel),
+                    },
+                }
+            });
+            setLineData(lineArr);
+        }
+    }
+
+    const getMapData = async () => {
+        const resp = await getColumnData();
+        if (resp) {
+            const mapData = resp;
+            let dataArr: any[] = [];//柱形图数据
+
+            mapData[0].qualityTypeList.forEach((a: any, index: number) => {
+                const tempArr = mapData.map((a: any) => {
+                    return {
+                        name: a.qualityTypeList[index].levelType,
+                        xname: a.labelName,
+                        value: Number(a.qualityTypeList[index].levelValue.replace("%", ""))
+                    }
+                });
+
+                dataArr = dataArr.concat([...tempArr]);
+            });
+            setMapData([...dataArr]);
+        }
+    }
+
+    useEffect(() => {
+        getTableDataFunc();
+        getMapData();
+    }, []);
+
+
+
+    return (
+        <MccsPageContainer>
+            <div className='content'>
+                <div className='blockTitle'>质量评级统计表单</div>
+                <div className='tableWrap'>
+                    <div className='columnsWrap'>
+                        <div className='list'>类型</div>
+                        <div className='list'>要求</div>
+                        <div className='list'>现场查核</div>
+                        <div className='list'>目标</div>
+                        <div className='list'>自评</div>
+                        <div className='list'>系统评分</div>
+                    </div>
+                    <div className='row'>
+                        {
+                            tableData.map((item, index) => {
+                                return (
+                                    <div className='rowList' key={index}>
+                                        <div className='list'>{item.typeLevel}</div>
+                                        <div className='list'>{item.requirements}</div>
+                                        <div className='list'>{item.site}</div>
+                                        <div className='list'>{item.target}</div>
+                                        <div className='list'>{item.self}</div>
+                                        <div className='list'>{item.system}</div>
+                                    </div>
+                                )
+                            })
+                        }
+
+                    </div>
+                </div>
+                <div className='blockTitle'>质量评级分析图</div>
+
+                {
+                    lineData && (
+                        <Column
+                            data={mapData}
+                            isGroup={true}
+                            xField='xname'
+                            yField='value'
+                            seriesField='name'
+                            annotations={
+                                lineData
+                                // {
+                                //     type: 'line',
+                                //     start: ['min', 25],
+                                //     end: ['max', 25],
+                                //     text: {
+                                //       content: '要求值25%',
+                                //       position: 'right',
+                                //       offsetY: 18,
+                                //       style: { textAlign: 'right',fill: '#69D1CC',},
+
+                                //     },
+                                //     style: {
+                                //       lineDash: [5, 5],
+                                //       stroke: '#69D1CC',
+                                //     },
+                                // },
+                                // {
+                                //     type: 'line',
+                                //     start: ['min', 50],
+                                //     end: ['max', 50],
+                                //     text: {
+                                //       content: '要求值50%',
+                                //       position: 'right',
+                                //       offsetY: 18,
+                                //       style: { textAlign: 'right',fill: '#80ABFF',},
+
+                                //     },
+                                //     style: {
+                                //       lineDash: [5, 5],
+                                //       stroke: '#80ABFF',
+                                //     },
+                                // },
+                                // {
+                                //     type: 'line',
+                                //     start: ['min', 90],
+                                //     end: ['max', 90],
+                                //     text: {
+                                //       content: '要求值90%',
+                                //       position: 'right',
+                                //       offsetY: 18,
+                                //       style: { textAlign: 'right',fill: '#FFC080',},
+
+                                //     },
+                                //     style: {
+                                //       lineDash: [5, 5],
+                                //       stroke: '#FFC080',
+                                //     },
+                                // },
+                                // {
+                                //     type: 'line',
+                                //     start: ['min', 25],
+                                //     end: ['max', 25],
+                                //     text: {
+                                //       content: '要求值',
+                                //       position: 'right',
+                                //       offsetY: 18,
+                                //       style: { textAlign: 'right',fill: '#3377FF',},
+
+                                //     },
+                                //     style: {
+                                //       lineDash: [5, 5],
+                                //       stroke: '#3377FF',
+                                //     },
+                                // },
+                                // {
+                                //     type: 'line',
+                                //     start: ['min', 25],
+                                //     end: ['max', 25],
+                                //     text: {
+                                //       content: '要求值',
+                                //       position: 'right',
+                                //       offsetY: 18,
+                                //       style: { textAlign: 'right',fill: '#690',},
+
+                                //     },
+                                //     style: {
+                                //       lineDash: [5, 5],
+                                //       stroke: '#690',
+                                //     },
+                                // },
+                                // ]
+                            }
+                            label={{
+                                position: 'middle',
+                                content: function content(item) {
+                                    return '';
+                                },
+                                layout: [
+                                    { type: 'interval-adjust-position' },
+                                    { type: 'interval-hide-overlap' },
+                                    { type: 'adjust-color' },
+                                ],
+                            }}
+                            tooltip={{
+                                formatter: (datum: any) => {
+                                    return { name: datum.name, value: datum.value + '%' };
+                                },
+                            }}
+                            color={
+                                (_ref) => {
+                                    var type = _ref.name;
+                                    if (type === 'A') {
+                                        return '#69D1CC';
+                                    }
+                                    if (type === 'B') {
+                                        return '#80ABFF';
+                                    }
+                                    if (type === 'C') {
+                                        return '#FFC080';
+                                    }
+                                    if (type === 'D') {
+                                        return '#3377FF';
+                                    }
+                                    if (type === 'E') {
+                                        return '#690';
+                                    }
+                                    return '#3070F2';
+                                }
+                            }
+                            maxColumnWidth={40}
+
+                        />
+                    )
+                }
+            </div>
+        </MccsPageContainer>
+    )
+}
+
+export default QualityRating

+ 28 - 0
src/pages/KeepImprove/qualityRating/serve.ts

@@ -0,0 +1,28 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 09:05:36
+ * @LastEditTime: 2021-09-28 08:53:53
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/ qualityRating/serve.js
+ */
+
+
+
+import { request } from 'umi';
+
+//获取统计表单数据
+export const getTableData  = async ()=>{
+    
+        return request('/api/pfm/sysgeneralconfig/getFormStatistical', {
+            method: 'GET',
+        });
+}
+
+//获取柱形图数据
+export const getColumnData  = async ()=>{
+    
+    return request('/api/pfm/sysgeneralconfig/getStatistics', {
+        method: 'GET',
+    });
+}

+ 6 - 0
src/pages/KeepImprove/questionGather/index.less

@@ -0,0 +1,6 @@
+
+
+
+#reportFrame {
+    border: none;
+}

+ 29 - 0
src/pages/KeepImprove/questionGather/index.tsx

@@ -0,0 +1,29 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-28 13:57:19
+ * @LastEditTime: 2021-09-28 16:43:03
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/questionGatherAndRevise/index.tsx
+ */
+
+
+import React from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+
+import './index.less';
+
+
+type QuestionGatherAndReviseProps = {}
+
+const QuestionGatherAndRevise:React.FC<QuestionGatherAndReviseProps> = ()=>{
+    return (
+        <MccsPageContainer>
+            <iframe  id="reportFrame" src="http://8.136.135.180:8081/webroot/ReportServer?formlet=PFM/test/问题汇总.frm" width="100%" height="800px">
+            </iframe>
+        </MccsPageContainer>
+    )
+}
+
+export default QuestionGatherAndRevise
+

+ 6 - 0
src/pages/KeepImprove/questionGatherAndRevise/index.less

@@ -0,0 +1,6 @@
+
+
+
+#reportFrame {
+    border: none;
+}

+ 29 - 0
src/pages/KeepImprove/questionGatherAndRevise/index.tsx

@@ -0,0 +1,29 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-28 13:57:19
+ * @LastEditTime: 2021-09-28 16:29:05
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/KeepImprove/questionGatherAndRevise/index.tsx
+ */
+
+
+import React from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+
+import './index.less';
+
+
+type QuestionGatherAndReviseProps = {}
+
+const QuestionGatherAndRevise:React.FC<QuestionGatherAndReviseProps> = ()=>{
+    return (
+        <MccsPageContainer>
+            <iframe  id="reportFrame" src="http://8.136.135.180:8081/webroot/ReportServer?formlet=PFM/test/问题汇总与整改.frm" width="100%" height="800px">
+            </iframe>
+        </MccsPageContainer>
+    )
+}
+
+export default QuestionGatherAndRevise
+

+ 306 - 0
src/pages/PlatformMana/districtMana/index.jsx

@@ -0,0 +1,306 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:13
+ * @LastEditTime: 2021-09-28 10:11:43
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/index.js
+ */
+
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, Popconfirm} from 'antd';
+import React, { useState, useRef } from 'react';
+
+import { PageContainer} from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import { ModalForm, ProFormText, ProFormSelect, ProFormDependency } from '@ant-design/pro-form';
+import UpdateForm from './updateForm';
+
+import { getDistrictList, editDistrictList, delDistrict, addDistrict,getMainDistrictList } from './service';
+
+const DistrictMana = () => {
+  const columns = [
+    {
+      title: '医院/院区ID',
+      dataIndex: 'id',
+      key: 'id',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '医院名称',
+      dataIndex: 'name',
+      key: 'name',
+      ellipsis: true,
+      hideInSearch: false,
+    },
+    {
+      title: '是否为主院',
+      dataIndex: 'isHospital',
+      key: 'isHospital',
+      hideInSearch: true,
+      ellipsis: true,
+      render: (text) => <a>{text == 0 ? '是' : '否'}</a>,
+    },
+    {
+      title: '医院标识',
+      dataIndex: 'sign',
+      key: 'sign',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '医院Id',
+      dataIndex: 'parentId',
+      key: 'parentId',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '主医院名',
+      dataIndex: 'parentName',
+      key: 'parentName',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '创建时间',
+      dataIndex: 'createDateTime',
+      key: 'createDateTime',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title:'操作',
+      dataIndex: 'option',
+      valueType: 'option',
+      render: (_, record) => [
+        <a
+          key="config"
+          onClick={() => {
+            handleUpdateModalVisible(true);
+            setCurrentRow(record);
+          }}
+        >
+          编辑
+        </a>,
+        <Popconfirm
+          key="subscribeAlert"
+          title="是否确定删除?"
+          onConfirm={() => {
+            setCurrentRow(record);
+            delListHandler(record);
+          }}
+        >
+          <a>删除</a>
+        </Popconfirm>,
+      ],
+    },
+  ];
+
+  const [createModalVisible, handleModalVisible] = useState(false);
+  const [updateModalVisible, handleUpdateModalVisible] = useState(false);
+  const actionRef = useRef();
+  const ref = useRef();   //新增表单
+  const [currentRow, setCurrentRow] = useState({});
+
+  /**
+   *
+   * @param {Boolean} bool 弹窗展示状态
+   */
+  const updateModalVisibleChange = (bool) => {
+    handleUpdateModalVisible(bool);
+    if (!bool) setCurrentRow(undefined);
+  };
+
+  //获取科室列表
+  const getList = async (params = {}, sort, filter) => {
+    const res = await getDistrictList(params);
+    // console.log({res});
+    return {
+      data: res.data.list,
+      total: res.data.totalCount,
+      success: res.success,
+    };
+  };
+
+  /**
+   *
+   * @param {Object} value 删除项数据
+   */
+  const delListHandler = async (value) => {
+    const resp = await delDistrict(value);
+    // console.log({ resp });
+    if (resp) {
+      if (actionRef.current) {
+        actionRef.current.reload();
+      }
+    }
+  };
+
+  // useEffect(()=>{
+  //   CARequest('/api/costAccount/hosptail/list');
+  // },[]);
+
+  return (
+    <PageContainer>
+      <ProTable
+        columns={columns}
+        request={getList}
+        actionRef={actionRef}
+        rowKey="id"
+        toolBarRender={() => [
+          <Button
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+            onClick={() => {
+              handleModalVisible(true);
+            }}
+          >
+            新增
+          </Button>
+        ]}
+
+        pagination={{
+          pageSize: 10,
+        }}
+        search={{
+          defaultCollapsed: false,
+          labelWidth: 'auto',
+        }}
+
+      />
+
+      <ModalForm
+        title="新增医院"
+        width="800px"
+        labelCol={{ span: 3, offset: 3 }}
+        layout={'horizontal'}
+        formRef={ref}
+        visible={createModalVisible}
+        onVisibleChange={(bool) => {
+          if (ref.current) {
+            ref.current.resetFields();
+          }
+          handleModalVisible(bool);
+        }}
+        onFinish={async (value) => {
+          const {name,isHospital,id,sign} = value;
+          const success = await addDistrict(isHospital==0?{
+            name,isHospital,sign
+          }:{
+            name,isHospital,parentId:id
+          });
+          //   console.log({ success });
+          if (success) {
+            handleModalVisible(false);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+        }}
+      >
+        <ProFormText
+          label="医院名"
+          rules={[
+            {
+              required: true,
+              message:'医院名是必填项',
+            },
+          ]}
+          width="sm"
+          name="name"
+        />
+        <ProFormSelect
+          rules={[
+            {
+              required: true,
+              message:'请选择是否为主院',
+            },
+          ]}
+          options={[
+            {
+              value: 0,
+              label: '是',
+            },
+            {
+              value: 1,
+              label: '否',
+            },
+          ]}
+          width="xs"
+          name="isHospital"
+          label="是否为主院"
+        />
+
+        <ProFormDependency name={['isHospital']}>
+          {({ isHospital }) => {
+            return isHospital == 0 ? (
+              <ProFormText
+                label="医院标识"
+                rules={[
+                  {
+                    required: true,
+                    message:'',
+                  },
+                ]}
+                width="sm"
+                name="sign"
+              />
+            ) : <></>;
+          }}
+        </ProFormDependency>
+        <ProFormDependency name={['isHospital']}>
+          {({ isHospital }) => {
+            return isHospital == 1 ? (
+              <ProFormSelect
+                name="id"
+                label="选择主医院"
+                request={async () =>{
+                      const resp = await getMainDistrictList();                      
+                      if(resp){
+                        return resp.map(item=>({
+                          label:item.name,
+                          value:item.id
+                        }))
+                      }
+                }}
+                placeholder=""
+                width='sm'
+                rules={[{ required: true, message: '请选择主医院ID' }]}
+              />
+            ) : <></>
+          }}
+        </ProFormDependency>
+      </ModalForm>
+
+      {/* 更新 */}
+      <UpdateForm
+        onSubmit={async (value) => {
+          // console.log({ '编辑': value });
+          const success = await editDistrictList(value);
+
+          if (success) {
+            handleUpdateModalVisible(false);
+            setCurrentRow(undefined);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+        }}
+        onCancel={() => {
+          handleUpdateModalVisible(false);
+          setCurrentRow(undefined);
+        }}
+        updateModalVisible={updateModalVisible}
+        updateModalVisibleChange={updateModalVisibleChange}
+        values={currentRow || {}}
+      />
+    </PageContainer>
+  );
+};
+
+export default DistrictMana;

+ 59 - 0
src/pages/PlatformMana/districtMana/service.js

@@ -0,0 +1,59 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 08:54:08
+ * @LastEditTime: 2021-09-28 09:51:26
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/DepartmentMana/service.js
+ */
+
+import { request } from 'umi';
+
+
+//获取所有医院列表
+export async function getDistrictList(params, options) {
+    return request('/api/pfm/hosptail/list', {
+      method: 'GET',
+      params:{...params},
+      ...(options || {}),
+    });
+}
+
+//获取主医院列表
+export async function getMainDistrictList(params, options) {
+  return request('/api/pfm/hosptail/getAll', {
+    method: 'GET',
+    params:{...params},
+    ...(options || {}),
+  });
+}
+
+//编辑医院
+export async function editDistrictList(body, options) {
+  return request('/api/pfm/hosptail/update', {
+    method: 'POST',
+    data:{...body},
+    ...(options || {}),
+  });
+}
+
+//新增医院
+export async function addDistrict(body, options) {
+  return request('/api/pfm/hosptail/save', {
+    method: 'POST',
+    data:{...body},
+    ...(options || {}),
+  });
+}
+
+//删除医院
+export async function delDistrict(params, options) {
+  const {id} = params;
+  const ids = [id];
+  return request(`/api/pfm/hosptail/delete`, {
+    method: 'POST',
+    data:ids,
+    ...(options || {}),
+  });
+}
+

+ 121 - 0
src/pages/PlatformMana/districtMana/updateForm.jsx

@@ -0,0 +1,121 @@
+import React,{useState} from 'react';
+import {
+  ProFormSelect,
+  ProFormText,
+  ModalForm,
+  ProFormDependency
+} from '@ant-design/pro-form';
+
+import { getMainDistrictList } from './service';
+
+
+const UpdateForm = (props) => {
+  const { updateModalVisible, updateModalVisibleChange, values, onSubmit } = props;
+  const [selectedHosp,setSelectedHosp] = useState({});
+  // console.log({values});
+  return (
+    <>
+      {
+        JSON.stringify(values) !== '{}' && <ModalForm
+          title="编辑医院"
+          width="800px"
+          initialValues={{ ...values }}
+          labelCol={{ span: 3, offset: 3 }}
+          layout={'horizontal'}
+          visible={updateModalVisible}
+          onVisibleChange={(visible) => updateModalVisibleChange(visible)}
+          onFinish={(value) => onSubmit({ ...values, ...value,parentName:selectedHosp.name})}
+        >
+          <ProFormText
+            label="医院名"
+            rules={[
+              {
+                required: true,
+                message:'医院名是必填项',
+              },
+            ]}
+            width="sm"
+            name="name"
+          />
+          <ProFormSelect
+            // initialValue={parseInt(values.isHospital)}
+            rules={[
+              {
+                required: true,
+                message:'请选择是否为主院',
+              },
+            ]}
+            options={[
+              {
+                value: 0,
+                label: '是',
+              },
+              {
+                value: 1,
+                label: '否',
+              },
+            ]}
+            width="xs"
+            name="isHospital"
+            label="是否为主院"
+          />
+
+          <ProFormDependency name={['isHospital']}>
+            {({ isHospital }) => {
+              return isHospital == 0 ? (
+                <ProFormText
+                  label="医院标识"
+                  rules={[
+                    {
+                      required: false,
+                      message:'',
+                    },
+                  ]}
+                  width="sm"
+                  name="sign"
+                />
+              ) : <></>;
+            }}
+          </ProFormDependency>
+          <ProFormDependency name={['isHospital']}>
+          {({ isHospital }) => {
+            return isHospital == 1 ? (
+              <ProFormSelect
+                name="parentId"
+                label="选择主医院"
+                request={async () =>{
+                      const resp = await getMainDistrictList();
+                      const {status,data=[],} = resp;
+                      
+                      if(status == 200){
+                        return data.map(item=>({
+                          label:item.name,
+                          value:item.id
+                        }))
+                      }
+                }}
+                fieldProps={{
+                  onChange: async (val) => {
+                    const resp = await getMainDistrictList();
+                    const {status,data,} = resp;
+                    if(status==200){
+                        const needItem = data.filter(item => item.id == val);
+                        needItem.length>0&&setSelectedHosp(needItem[0]);
+                    }
+                    
+                  },
+                }}
+                placeholder="请选择主医院"
+                width='sm'
+                rules={[{ required: true, message: '请选择主医院' }]}
+              />
+            ) : <></>
+          }}
+        </ProFormDependency>
+        </ModalForm>
+      }
+    </>
+  );
+};
+
+export default UpdateForm;

+ 19 - 0
src/pages/PlatformMana/generalSetting/index.less

@@ -0,0 +1,19 @@
+
+
+
+
+.block {
+    background: #FFFFFF;
+    border-radius: 2px;
+    margin-bottom: 20px;
+    padding-bottom: 20px;
+    .blockTitle {
+        font-size: 16px;
+        font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+        font-weight: bold;
+        color: #292C33;
+        padding: 16px 24px;
+        border-bottom: 1px solid #DADEE6;
+        margin-bottom: 20px;
+    }
+}

+ 394 - 0
src/pages/PlatformMana/generalSetting/index.tsx

@@ -0,0 +1,394 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 10:41:52
+ * @LastEditTime: 2021-09-29 18:07:34
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/PlatformMana/generalSetting/index.tsx
+ */
+
+
+import React, { useState } from 'react'
+import MccsPageContainer from '@/components/MccsPageContainer/index';
+import MccsEditableTable from '@/components/MccsEditableTable/index';
+import { Checkbox } from 'antd';
+import { getAccreditationTypeData, addTableData, editTableData, getScoreLevelData,getLedgerType,delTableData } from './serve';
+
+import './index.less';
+
+
+type GeneralSettingType = {
+
+}
+
+const GeneralSetting: React.FC<GeneralSettingType> = () => {
+
+    const [currentType, setCurrentType] = useState<number>();
+    const [reloadTableOne, setReloadTableOne] = useState(false);
+    const [reloadTableTwo, setReloadTableTwo] = useState(false);
+    const [reloadTableThree, setReloadTableThree] = useState(false);
+
+    const accreditationColumns = [
+        {
+            title: '序号',
+            key: 'id',
+            dataIndex: 'id',
+            editable: false
+        },
+        {
+            title: '名称',
+            key: 'generalName',
+            dataIndex: 'generalName',
+        },
+        {
+            title: '组别类型',
+            key: 'categoryType',
+            dataIndex: 'categoryType',
+        },
+        {
+            title: '操作',
+            valueType: 'option',
+            width: 200,
+            render: (text: any, record: any, _: any, action: any) => [
+                <a
+                    key="editable"
+                    onClick={() => {
+                        action?.startEditable?.(record.id);
+                    }}
+                >
+                    编辑
+                </a>,
+                <a
+                    key="delete"
+                    onClick={() => {
+                        delData(record.id,1)
+                    }}
+                >
+                    删除
+                </a>,
+            ],
+        },
+    ];
+    const scoreLevelColumns = [
+        {
+            title: '序号',
+            key: 'id',
+            dataIndex: 'id',
+            editable: false
+        },
+        {
+            title: '等级分数',
+            key: 'levelNumber',
+            dataIndex: 'levelNumber',
+        },
+        {
+            title: '要求',
+            key: 'requirements',
+            dataIndex: 'requirements',
+        },
+        {
+            title: '备注',
+            key: 'configNote',
+            dataIndex: 'configNote',
+            ellipsis:true,
+            width:'40%'
+        },
+        {
+            title: '是否启用',
+            key: 'configStatus',
+            dataIndex: 'configStatus',
+            valueType: 'select',
+            width:'10%',
+            valueEnum: {
+                1: {
+                    text: '是',
+                    value:1
+                },
+                0: {
+                    text: '否',
+                    value:0
+                },
+            },
+
+        },
+        {
+            title: '操作',
+            valueType: 'option',
+            width: 200,
+            render: (text: any, record: any, _: any, action: any) => [
+                <a
+                    key="editable"
+                    onClick={() => {
+                        action?.startEditable?.(record.id);
+                    }}
+                >
+                    编辑
+                </a>,
+                <a
+                    key="delete"
+                    onClick={() => {
+                        delData(record.id,2)
+                    }}
+                >
+                    删除
+                </a>,
+            ],
+        },
+    ];
+
+    const uploadLedgerColumns = [
+        {
+            title: '序号',
+            key: 'id',
+            dataIndex: 'id',
+            editable: false
+        },
+        {
+            title: '等级分数',
+            key: 'levelNumber',
+            dataIndex: 'levelNumber',
+        },
+        {
+            title: '类型名称',
+            key: 'generalName',
+            dataIndex: 'generalName',
+        },
+        {
+            title: '备注',
+            key: 'configNote',
+            dataIndex: 'configNote',
+            width:'40%',
+            ellipsis:true
+        },
+        {
+            title: '是否启用',
+            key: 'configStatus',
+            dataIndex: 'configStatus',
+            valueType: 'select',
+            width:'15%',
+            valueEnum: {
+                1: {
+                    text: '是',
+                    value:1
+                },
+                0: {
+                    text: '否',
+                    value:0
+                },
+            },
+
+        },
+        {
+            title: '操作',
+            valueType: 'option',
+            width: 200,
+            render: (text: any, record: any, _: any, action: any) => [
+                <a
+                    key="editable"
+                    onClick={() => {
+                        action?.startEditable?.(record.id);
+                    }}
+                >
+                    编辑
+                </a>,
+                <a
+                    key="delete"
+                    onClick={() => {
+                        delData(record.id,3)
+                    }}
+                >
+                    删除
+                </a>,
+            ],
+        },
+    ];
+
+    const getTableDataRequest = async () => {
+
+        const respData = await getAccreditationTypeData();
+        if (respData) {
+            setReloadTableOne(false);
+            return {
+                data: respData,
+                success: true
+            }
+        }
+    }
+
+    const getLevelScoreTableDataRequest = async () => {
+        //获取等级分数
+        const respData = await getScoreLevelData();
+        if (respData) {
+            const _respData = respData.map((t:any)=>({...t,configStatus:`${t.configStatus}`})); //Columns的key只可以是string
+            setReloadTableTwo(false);
+            return {
+                data: _respData,
+                success: true
+            }
+        }
+    }
+
+    const getLedgerTableDataRequest = async () => {
+        //获取台账类型数据
+        const respData = await getLedgerType();
+        if (respData) {
+            const _respData = respData.map((t:any)=>({...t,configStatus:`${t.configStatus}`}));//Columns的key只可以是string
+            setReloadTableThree(false);
+            return {
+                data: _respData,
+                success: true
+            }
+        }
+    }
+
+
+
+    type dataType = {
+        id: string | number,
+        categoryType?: string,
+        configNote?: string,
+        configStatus?: number,
+        generalName?: string,
+        levelNumber?: string,
+        requirements?: string
+    }
+
+    const addData = async (data: dataType, typeNum: number) => {
+        const { categoryType,configStatus,requirements,levelNumber,configNote, generalName} = data;
+        if (typeNum == 1) {
+            //条文组别类型新增
+            const postData: API.AddtableDataPostType = {
+                configType: typeNum,
+                categoryType,
+                generalName
+            }
+            const resp = await addTableData(postData);
+            if (resp) {
+                setReloadTableOne(true);
+            }
+        }
+        if (typeNum == 2) {
+            //条文组别类型新增
+            const postData: API.AddtableDataPostType = {
+                configType: typeNum,
+                configStatus:Number(configStatus),
+                levelNumber,
+                configNote,
+                requirements
+            }
+            const resp = await addTableData(postData);
+            if (resp) {
+                setReloadTableTwo(true);
+            }
+        }
+        if (typeNum == 3) {
+            //条文组别类型新增
+            const postData: API.AddtableDataPostType = {
+                configType: typeNum,
+                configStatus:Number(configStatus),
+                generalName,
+                levelNumber,
+                configNote,
+            }
+            const resp = await addTableData(postData);
+            if (resp) {
+                setReloadTableThree(true);
+            }
+        }
+
+    }
+
+    const delData = async (id:number,typeNum:number)=>{
+          const resp = await delTableData(id);
+          if(resp){
+            typeNum==1&&setReloadTableOne(true);
+            typeNum==2&&setReloadTableTwo(true);
+            typeNum==3&&setReloadTableThree(true);
+          }
+    }
+
+    const editDataHandle = async (data: dataType, typeNum: number) => {
+        const { categoryType,configStatus,requirements,levelNumber,configNote, generalName, id } = data;
+        if (typeNum == 1) {
+            //条文组别类型新增
+            const postData: API.EdittableDataPostType = {
+                configType: typeNum,
+                categoryType,
+                generalName,
+                id: Number(id)
+            }
+            const resp = await editTableData(postData);
+
+            if (resp) {
+                setReloadTableOne(true);
+            }
+        }
+        if (typeNum == 2) {
+            //条文组别类型新增
+            const postData: API.EdittableDataPostType = {
+                configType: typeNum,
+                configStatus:Number(configStatus),
+                levelNumber,
+                configNote,
+                id: Number(id),
+                requirements
+            }
+            const resp = await editTableData(postData);
+            if (resp) {
+                setReloadTableTwo(true);
+            }
+        }
+        if (typeNum == 3) {
+            //条文组别类型新增
+            const postData: API.EdittableDataPostType = {
+                configType: typeNum,
+                configStatus:Number(configStatus),
+                generalName,
+                levelNumber,
+                configNote,
+                id: Number(id)
+            }
+            const resp = await editTableData(postData);
+            if (resp) {
+                setReloadTableThree(true);
+            }
+        }
+    }
+
+    return (
+        <MccsPageContainer>
+            <div className='block'>
+                <div className='blockTitle'>评审细则类型设置</div>
+                <MccsEditableTable
+                    columns={accreditationColumns}
+                    request={getTableDataRequest}
+                    addHandle={(data) => addData(data, 1)}
+                    editHandle={data => editDataHandle(data, 1)}
+                    reload={reloadTableOne}
+                />
+            </div>
+            <div className='block'>
+                <div className='blockTitle'>分数等级设置</div>
+                <MccsEditableTable
+                    columns={scoreLevelColumns}
+                    request={getLevelScoreTableDataRequest}
+                    addHandle={(data) => addData(data, 2)}
+                    editHandle={data => editDataHandle(data, 2)}
+                    reload={reloadTableTwo}
+                />
+            </div>
+            <div className='block'>
+                <div className='blockTitle'>台账类型设置</div>
+                <MccsEditableTable
+                    columns={uploadLedgerColumns}
+                    request={getLedgerTableDataRequest}
+                    addHandle={(data) => addData(data, 3)}
+                    editHandle={data => editDataHandle(data, 3)}
+                    reload={reloadTableThree}
+                />
+            </div>
+        </MccsPageContainer>
+    )
+}
+
+export default GeneralSetting

+ 66 - 0
src/pages/PlatformMana/generalSetting/serve.ts

@@ -0,0 +1,66 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 11:06:43
+ * @LastEditTime: 2021-09-29 17:51:55
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/PlatformMana/generalSetting/serve.ts
+ */
+
+
+import { request } from 'umi';
+
+//获取评审细则类型数据
+export const getAccreditationTypeData  = async ()=>{
+    
+        return request('/api/pfm/sysgeneralconfig/getReviewRulesConfig', {
+            method: 'GET',
+        });
+}
+
+
+
+
+//添加数据
+export const addTableData  = async (data:API.AddtableDataPostType)=>{
+    
+    return request('/api/pfm/sysgeneralconfig/addSysGeneralConfig', {
+        method: 'POST',
+        data:data
+    });
+}
+
+//编辑数据
+export const editTableData  = async (data:API.EdittableDataPostType)=>{
+    
+    return request('/api/pfm/sysgeneralconfig/updateSysGeneralConfig', {
+        method: 'POST',
+        data:data
+    });
+}
+
+
+//获取分数等级数据
+export const getScoreLevelData  = async ()=>{
+    
+    return request('/api/pfm/sysgeneralconfig/getScoreConfig', {
+        method: 'GET',
+    });
+}
+
+//获取台账类型数据
+export const getLedgerType  = async ()=>{
+    
+    return request('/api/pfm/sysgeneralconfig/getAccountConfig', {
+        method: 'GET',
+    });
+}
+
+//删除数据
+export const delTableData  = async (id:number)=>{
+    
+    return request('/api/pfm/sysgeneralconfig/deleteSysGeneralConfig', {
+        method: 'POST',
+        params:{id}
+    });
+}

+ 31 - 0
src/pages/PlatformMana/generalSetting/typings.d.ts

@@ -0,0 +1,31 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-27 14:09:59
+ * @LastEditTime: 2021-09-28 16:58:35
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/PlatformMana/generalSetting/typings.d.ts
+ */
+
+
+declare namespace API {
+    type AddtableDataPostType = {
+        configType:number,
+        categoryType?:string,
+        configNote?:string,
+        configStatus?:number,
+        generalName?:string,
+        levelNumber?:string,
+        requirements?:string
+    }
+    type EdittableDataPostType = {
+        categoryType?:string,
+        configNote?:string,
+        configStatus?:number,
+        configType:number,
+        generalName?:string,
+        id:number,
+        levelNumber?:string,
+        requirements?:string
+    }
+}

+ 318 - 0
src/pages/PlatformMana/menuManage/index.js

@@ -0,0 +1,318 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:13
+ * @LastEditTime: 2021-09-28 10:10:29
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/index.js
+ */
+
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, Popconfirm } from 'antd';
+import React, { useState, useRef } from 'react';
+
+import { PageContainer } from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import { ModalForm, ProFormText, ProFormSelect, ProFormDigit } from '@ant-design/pro-form';
+import UpdateForm from './updateForm';
+import { addList, editList, delList } from './service';
+import { getMenuList } from '@/pages/PlatformMana/menuManage/service';
+
+const UserMana = () => {
+  const columns = [
+    {
+      title: '菜单名称',
+      dataIndex: 'name',
+      key: 'name',
+      // ellipsis: true,
+    },
+    {
+      title: '菜单Id',
+      dataIndex: 'menuId',
+      key: 'menuId',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: 'URL',
+      dataIndex: 'url',
+      key: 'url',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: 'Path',
+      dataIndex: 'path',
+      key: 'path',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '变更人',
+      dataIndex: 'modifyUserName',
+      key: 'modifyUserName',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '变更日期',
+      dataIndex: 'modifyTime',
+      key: 'modifyTime',
+      valueType: 'date',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '操作',
+      dataIndex: 'option',
+      valueType: 'option',
+      render: (_, record) => {
+        const { type } = record;
+        const btnGroups = [
+          <a
+            key="config"
+            onClick={() => {
+              handleUpdateModalVisible(true);
+              setCurrentRow(record);
+            }}
+          >
+            编辑
+          </a>,
+          <Popconfirm
+            key="subscribeAlert"
+            title="是否确定删除?"
+            onConfirm={() => {
+              delUserHandler(record);
+            }}
+          >
+            <a>删除</a>
+          </Popconfirm>,
+        ];
+        return type != 0
+          ? [...btnGroups]
+          : [
+              <a
+                key="config"
+                onClick={() => {
+                  setIfAddZeroLevelMenu(false);
+                  handleModalVisible(true);
+                  setCurrentRow(record);
+                }}
+              >
+                添加
+              </a>,
+              ...btnGroups,
+            ];
+      },
+    },
+  ];
+
+  const [createModalVisible, handleModalVisible] = useState(false);
+  const [updateModalVisible, handleUpdateModalVisible] = useState(false);
+  const actionRef = useRef();
+  const [currentRow, setCurrentRow] = useState(undefined);
+  const [ifAddZeroLevelMenu, setIfAddZeroLevelMenu] = useState(true);
+
+  // const [shareParamsSetting,setShareParamsSetting] = useState(false);  //是否分摊参数设置
+
+  /**
+   *
+   * @param {Boolean} bool 弹窗展示状态
+   */
+  const updateModalVisibleChange = (bool) => {
+    handleUpdateModalVisible(bool);
+    if (!bool) setCurrentRow(undefined);
+  };
+
+  //获取Drawer菜单列表
+  const getMenus = async (params = {}, sort, filter) => {
+    const res = await getMenuList(params);
+    if(res){
+      return {
+        data: res.list,
+        total: res.totalCount,
+        success:true,
+      };
+    }
+  };
+
+  /**
+   *
+   * @param {Object} value 删除项数据
+   */
+  const delUserHandler = async (value) => {
+    const ids = [value.menuId];
+    const resp = await delList({ ids });
+    if (resp) {
+      if (actionRef.current) {
+        actionRef.current.reload();
+      }
+    }
+  };
+
+  return (
+    <PageContainer>
+      <ProTable
+        columns={columns}
+        request={getMenus}
+        actionRef={actionRef}
+        rowKey="menuId"
+        toolBarRender={() => [
+          <Button
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+            onClick={() => {
+              setIfAddZeroLevelMenu(true);
+              handleModalVisible(true);
+            }}
+          >
+            新增
+          </Button>,
+        ]}
+        pagination={{
+          pageSize: 10,
+        }}
+        search={false}
+      />
+
+      <ModalForm
+        title="新增菜单"
+        width="800px"
+        labelCol={{ span: 5, offset: 3 }}
+        layout={'horizontal'}
+        modalProps={{
+          destroyOnClose: true,
+        }}
+        visible={createModalVisible}
+        onVisibleChange={handleModalVisible}
+        onFinish={async (value) => {
+          let id = 0;
+          currentRow && (id = currentRow.menuId);
+          // console.log({id});
+          const resp = await addList({ ...value, parentId: id });
+          if (resp) {
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+            return true;
+          }
+          setCurrentRow(undefined);
+        }}
+      >
+        <ProFormText
+          label="菜单名称"
+          rules={[
+            {
+              required: true,
+              message: '角色名是必填项!',
+            },
+          ]}
+          width="sm"
+          name="name"
+          placeholder="请输入菜单"
+        />
+        <ProFormText
+          label="Path"
+          rules={[
+            {
+              required: true,
+              message: '菜单路径是必填项!',
+            },
+          ]}
+          width="sm"
+          name="path"
+        />
+        {/* <ProFormText
+          label="权限字段"
+          rules={[
+            {
+              required: true,
+              message: '权限字段是必填项!',
+            },
+          ]}
+          width="sm"
+          name="perms"
+          placeholder="请输入"
+        /> */}
+        <ProFormSelect
+          name="type"
+          label="类型"
+          width="sm"
+          options={[
+            { label: '目录', value: 0 },
+            { label: '菜单', value: 1 },
+            { label: '按钮', value: 2 },
+          ]}
+          fieldProps={{
+            optionItemRender(item) {
+              return item.label + ' - ' + item.value;
+            },
+          }}
+          placeholder="请选择类型"
+          rules={[{ required: true, message: '请选择类型!' }]}
+        />
+        <ProFormText
+          label="菜单Icon"
+          rules={[
+            {
+              required: false,
+            },
+          ]}
+          width="sm"
+          name="icon"
+        />
+        <ProFormDigit
+          label="菜单排序"
+          rules={[
+            {
+              required: false,
+            },
+          ]}
+          width="sm"
+          name="orderNum"
+          placeholder="请选择菜单序号"
+        />
+      </ModalForm>
+
+      {/* 更新 */}
+      <UpdateForm
+        onSubmit={async (value) => {
+          const { menuId, parentId = 0 } = currentRow;
+          // console.log({currentRow});
+          // console.log({'编辑':value});
+          const { name, path, url, perms, type, icon = 'ww', orderNum } = value;
+
+          const resp = await editList({
+            parentId,
+            name,
+            path,
+            url,
+            perms,
+            type,
+            icon,
+            orderNum,
+            id: menuId,
+          });
+          if (resp) {
+            handleUpdateModalVisible(false);
+            setCurrentRow(undefined);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+        }}
+        onCancel={() => {
+          handleUpdateModalVisible(false);
+          setCurrentRow(undefined);
+        }}
+        updateModalVisible={updateModalVisible}
+        updateModalVisibleChange={updateModalVisibleChange}
+        values={currentRow || {}}
+      />
+    </PageContainer>
+  );
+};
+
+export default UserMana;

+ 69 - 0
src/pages/PlatformMana/menuManage/service.js

@@ -0,0 +1,69 @@
+/*
+ * @Author: your name
+ * @Date: 2021-08-03 14:38:54
+ * @LastEditTime: 2021-09-28 09:51:43
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /CostAccountManaSys/src/pages/platformMana/menuManage/service.js
+ */
+
+
+
+import { request } from 'umi';
+
+//获角色列表
+export async function getMenuList(params, options) {
+    return request('/api/pfm/menu/list', {
+      method: 'GET',
+      params: {...params},
+      ...(options || {}),
+    });
+}
+
+//新增菜单
+export async function addList(body, options) {
+    return request('/api/pfm/menu/save', {
+      method: 'POST',
+      data: {...body},
+      ...(options || {}),
+    });
+}
+
+//编辑角色
+export async function editList(body, options) {
+  return request('/api/pfm/menu/edit', {
+    method: 'POST',
+    data: {...body},
+    ...(options || {}),
+  });
+}
+
+//删除角色
+export async function delList(params, options) {
+  const {ids} = params;
+  return request(`/api/pfm/menu/delete`, {
+    data:ids,
+    method: 'POST',
+    ...(options || {}),
+  });
+}
+
+// //根据角色查询已绑用户
+// export async function getUsersByRoleId(params, options) {
+//   const {roleId} = params;
+//   return request(`/api/costAccount/role/editUserRole`, {
+//     data:{roleId, userIds},
+//     method: 'POST',
+//     ...(options || {}),
+//   });
+// }
+
+//角色绑定用户
+export async function roleBindUser(params, options) {
+  const {roleId, userIds} = params;
+  return request(`/api/pfm/role/editUserRole`, {
+    data:{roleId, userIds},
+    method: 'POST',
+    ...(options || {}),
+  });
+}

+ 102 - 0
src/pages/PlatformMana/menuManage/updateForm.jsx

@@ -0,0 +1,102 @@
+import React from 'react';
+import {
+  ProFormText,
+  ModalForm,
+  ProFormSelect,
+  ProFormDigit
+} from '@ant-design/pro-form';
+
+
+
+const UpdateForm = (props) => {
+  const { updateModalVisible, updateModalVisibleChange, values, onSubmit } = props;
+  return (
+    <>
+      {
+        JSON.stringify(values) !== '{}' && <ModalForm
+          title="编辑菜单"
+          width="800px"
+          initialValues={{ ...values }}
+          labelCol={{ span: 5, offset: 3 }}
+          layout={'horizontal'}
+          visible={updateModalVisible}
+          onVisibleChange={(visible) => updateModalVisibleChange(visible)}
+          onFinish={(value) => onSubmit({ ...values, ...value })}
+        >
+          <ProFormText
+            label="菜单名称"
+            rules={[
+              {
+                required: true,
+                message: '角色名是必填项!',
+              },
+            ]}
+            width="sm"
+            name="name"
+          />
+          <ProFormText
+            label="Path"
+            rules={[
+              {
+                required: true,
+                message: '菜单路径是必填项!',
+              },
+            ]}
+            width="sm"
+            name="path"
+          />
+          {/* <ProFormText
+            label="权限字段"
+            rules={[
+              {
+                required: true,
+                message: '权限字段是必填项!',
+              },
+            ]}
+            width="sm"
+            name="perms"
+          /> */}
+          <ProFormSelect
+            name="type"
+            label="类型"
+            width="sm"
+            options={[
+              { label: '目录', value: 0 },
+              { label: '菜单', value: 1 },
+              { label: '按钮', value: 2 },
+            ]}
+            fieldProps={{
+              optionItemRender(item) {
+                return item.label + ' - ' + item.value;
+              },
+            }}
+            placeholder="请选择类型"
+            rules={[{ required: true, message: '请选择类型!' }]}
+          />
+          <ProFormText
+            label="菜单Icon"
+            rules={[
+              {
+                required: false,
+              },
+            ]}
+            width="sm"
+            name="icon"
+          />
+          <ProFormDigit
+            label="菜单排序"
+            rules={[
+              {
+                required: false,
+              },
+            ]}
+            width="sm"
+            name="orderNum"
+          />
+        </ModalForm>
+      }
+    </>
+  );
+};
+
+export default UpdateForm;

+ 137 - 0
src/pages/PlatformMana/roleManage/component/drawer.jsx

@@ -0,0 +1,137 @@
+
+
+import React,{useState,useEffect,useRef} from 'react'
+// import { PageContainer } from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import {Table } from 'antd';
+import { DrawerForm } from '@ant-design/pro-form';
+import {deepGetVal,unique} from '@/utils';
+
+import './style.less';
+
+
+
+
+export default function DrawerContent(props) {
+
+    const { 
+        visible=false,
+        onVisibleChange=()=>{},
+        currentRow={},
+        renderListFunc=()=>{},
+        onFinishFunc=()=>{console.log('init onFinishFunc')},
+        columns=[],
+        defaultSelected=[],
+        config={},
+        title
+    } = props;
+    
+    const {rowKeys='id',tableSearch=false,} = config;
+    const drawerRef = useRef();
+    const [selectedKeys,setSelectedKeys] = useState([]);
+    const [defaultSelectedKeys,setDefaultSelectedKeys] = useState([]);
+    const [ifSearch,setIfSearch] = useState(false);
+    const [underSearchlist,setUnderSearchlist] = useState([]);
+
+    const renderDefault = ()=>{
+        const defaultSelects = defaultSelected;
+        setDefaultSelectedKeys(defaultSelected);
+        setSelectedKeys(defaultSelects);
+    }
+
+
+    useEffect(()=>{
+        renderDefault();
+    },[currentRow,defaultSelected])
+
+
+
+    return visible&&currentRow&&columns.length>0 ? (
+        <>
+            <DrawerForm
+                title={title}
+                visible={visible}
+                onVisibleChange={onVisibleChange}
+                formRef={drawerRef}
+                drawerProps={{
+                    forceRender: true,
+                    destroyOnClose: true,
+                }}
+                onFinish={async (values) => {
+                    //   console.log({onFinishFunc,values});
+                      onFinishFunc(values,defaultSelectedKeys);
+                }}
+            
+            >
+            
+                <ProTable
+                    columns={columns}
+                    rowKey={rowKeys}
+                    tableClassName="drawerContent"
+                    request={renderListFunc}
+                    layout={'inline'}
+                    search={{
+                        ...tableSearch,
+                        span:8,
+                    }}
+                    onSubmit={(u)=>{
+                        //  console.log({u});
+                        setIfSearch(true);
+                    }}
+                    onReset={()=>{setIfSearch(false);}}
+                    rowSelection={{
+                        // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom
+                        // 注释该行则默认不显示下拉选项
+                        hideSelectAll:true,
+                        selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+                        checkStrictly:false,
+                        selectedRowKeys:selectedKeys,
+                        onChange:(selectedRowKeys, selectedRows)=>{
+                            // console.log({selectedRowKeys,selectedRows});
+                            setSelectedKeys(selectedRowKeys);
+                            
+                        },
+                        onSelect:(record, selected, selectedRows, nativeEvent)=>{
+                            // console.log({record, selected, selectedRows, nativeEvent,ifSearch});
+                            if(tableSearch){
+
+                                let _defaultSelectedKeys = defaultSelectedKeys;
+                                let {children} = record;
+                                let arr=[]
+    
+                                if(children&&children.length>0){
+                                   arr = deepGetVal(children,rowKeys,'children');
+                                }
+                                arr.push(record[rowKeys]);
+    
+                                // console.log({arr,children});
+    
+                                if(!selected){
+                                    arr.forEach(val=>{
+                                        const index =  defaultSelectedKeys.findIndex(item=>item == val);
+                                    // console.log(index,record[rowKeys],defaultSelectedKeys)
+                                        if(index != -1){
+                                            _defaultSelectedKeys.splice(index,1);
+                                        }
+                                    });
+                                    _defaultSelectedKeys = unique(_defaultSelectedKeys);
+                                    setDefaultSelectedKeys(_defaultSelectedKeys);
+    
+                                }else{
+                                    let tempArr = _defaultSelectedKeys.concat(arr);
+                                    tempArr = unique(tempArr);
+                                    setDefaultSelectedKeys([].concat(tempArr));
+                                }
+
+                            }else {
+                                const keys = selectedRows.map(item=>item[rowKeys]);
+                                setDefaultSelectedKeys([].concat(keys));
+                            }
+                        }
+                    }}
+                />
+            
+            </DrawerForm>
+        </>
+    ) : <></>
+}

+ 7 - 0
src/pages/PlatformMana/roleManage/component/style.less

@@ -0,0 +1,7 @@
+
+
+
+
+.ant-col .ant-form-item-label {
+      flex: 1 !important;
+}

+ 409 - 0
src/pages/PlatformMana/roleManage/index.js

@@ -0,0 +1,409 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:13
+ * @LastEditTime: 2021-09-29 18:31:40
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/index.js
+ */
+
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, Popconfirm,Form} from 'antd';
+import React, { useState, useRef } from 'react';
+import { PageContainer } from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import { ModalForm, ProFormText,ProFormDateRangePicker } from '@ant-design/pro-form';
+import UpdateForm from './updateForm';
+import DrawerContent from './component/drawer';
+import { getRoleList, roleBindUser, addList, editList, delList,roleBindMenu,roleHasBindUsers,roleHasBindMenus } from './service';
+import { getUserList } from '@/pages/PlatformMana/userMana/service';
+
+import moment from 'moment';
+import 'moment/locale/zh-cn';
+import locale from 'antd/es/date-picker/locale/zh_CN';
+
+import { getMenuList } from '@/pages/PlatformMana/menuManage/service';
+
+const UserMana = () => {
+  const columns = [
+    {
+      title: '角色名',
+      dataIndex: 'roleName',
+      key: 'roleName',
+    },
+    {
+      title: '变更人',
+      dataIndex: 'modifyUserName',
+      key: 'modifyUserName',
+      hideInSearch: true,
+
+    },
+    {
+      title: '变更日期',
+      dataIndex: 'modifyTime',
+      key: 'modifyTime',
+      renderFormItem: (item, { type, defaultRender, formItemProps, fieldProps, ...rest }, form) => {
+
+        if (type === 'form') {
+          return null;
+        }
+        return (
+          <Form.Item >
+            <ProFormDateRangePicker  fieldProps={{locale: locale,onChange:(moment)=>{console.log(moment)} }} name="modifyTime" />
+          </Form.Item>
+        )
+      },
+    },
+    {
+      title: '操作',
+      dataIndex: 'option',
+      valueType: 'option',
+      render: (_, record) => [
+        <a
+          key="config"
+          onClick={() => {
+            bindInitHandle(record,'user');
+          }}
+        >
+          用户
+        </a>,
+        <a
+          key="config"
+          onClick={() => {
+            bindInitHandle(record,'menu');
+          }}
+        >
+          权限
+        </a>,
+        <a
+          key="config"
+          onClick={() => {
+            handleUpdateModalVisible(true);
+            setCurrentRow(record);
+          }}
+        >
+          编辑
+        </a>,
+        <Popconfirm
+          key="subscribeAlert"
+          title="是否确定删除?"
+          onConfirm={() => {
+            delUserHandler(record);
+          }}
+        >
+          <a>删除</a>
+        </Popconfirm>,
+      ],
+    },
+  ];
+
+  const DrawerTableUsersColumns = [
+    {
+      title: 'Id',
+      dataIndex: 'id',
+      key: 'id',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '姓名',
+      dataIndex: 'name',
+      key: 'name',
+      ellipsis: true,
+    },
+    {
+      title: '用户名',
+      dataIndex: 'account',
+      key: 'account',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '在职状态',
+      dataIndex: 'hospitalStatus',
+      key: 'hospitalStatus',
+      hideInSearch: true,
+      ellipsis: true,
+      render:num=><>{num==0?'离职':'在职'}</>
+    },
+  ];
+  
+  const DrawerTableMenusColumns = [
+    {
+      title: 'Id',
+      dataIndex: 'menuId',
+      key: 'menuId',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '菜单名称',
+      dataIndex: 'name',
+      key: 'name',
+      ellipsis: true,
+    }
+  ];
+
+  const [createModalVisible, handleModalVisible] = useState(false);
+  const [updateModalVisible, handleUpdateModalVisible] = useState(false);
+  const actionRef = useRef();
+  const [currentRow, setCurrentRow] = useState({});
+  const [editRoleBindUsers, setEditRoleBindUsers] = useState(false);
+  const [drawerVisible, setDrawerVisible] = useState(false);
+
+
+  const [selectedUsers,setSelectedUsers] = useState([]);
+  const [selectedMenus,setSelectedMenus] = useState([]);
+
+  // const [shareParamsSetting,setShareParamsSetting] = useState(false);  //是否分摊参数设置
+
+  /**
+   *
+   * @param {Boolean} bool 弹窗展示状态
+   */
+  const updateModalVisibleChange = (bool) => {
+    handleUpdateModalVisible(bool);
+    if (!bool) setCurrentRow(undefined);
+  };
+
+  //获取列表
+  const getList = async (params = {}, sort, filter) => {
+    //format: (value) => { return [value[0].format('YYYY-MM-DD'),value[1].format('YYYY-MM-DD')] }
+    const {pageSize,current,modifyTime,roleName:keyword} = params;
+    const query = modifyTime?{pageSize,current,keyword,startDate:moment(modifyTime[0]).format('YYYY-MM-DD'),endDate:moment(modifyTime[1]).format('YYYY-MM-DD')}:{pageSize,current,keyword}
+    const res = await getRoleList(query);
+    if(res){
+      return {
+        data: res.list,
+        total: res.totalCount,
+        success:true,
+      };
+    }
+  };
+
+  //获取Drawer用户列表
+  const getUsers = async (params = {}, sort, filter) => {
+    const res = await getUserList(params);
+    if(res){
+      return {
+        data: res.list,
+        total: res.totalCount,
+        success: true,
+      };
+    }
+  };
+
+  //获取Drawer菜单列表
+  const getMenus = async (params = {}, sort, filter) => {
+    const res = await getMenuList(params);
+    if(res){
+      return {
+        data: res.list,
+        total: res.totalCount,
+        success:true,
+      };
+    }
+  };
+
+  /**
+   *
+   * @param {Object} value 删除项数据
+   */
+  const delUserHandler = async (value) => {
+    const ids = [value.roleId];
+    const resp = await delList({ ids });
+    if (resp) {
+      if (actionRef.current) {
+        actionRef.current.reload();
+      }
+    }
+  };
+  
+  //绑定初始化
+  /**
+   * 
+   * @param {Object} record 
+   * @param {String} type   user/menu
+   */
+  const bindInitHandle = async (record,type)=>{
+    const {roleId} = record;
+    
+    if(type == 'user'){
+      const resp = await roleHasBindUsers({roleId});
+      if(resp){
+        const tempArr = resp.map(item=>item.id);
+        setSelectedUsers(tempArr);
+      }
+      setEditRoleBindUsers(true);
+    }
+    if(type == 'menu'){
+      const resp = await roleHasBindMenus({roleId});
+      if(resp){
+        const tempArr = resp.map(item=>item.id);
+        setSelectedMenus(tempArr);
+      }
+      setEditRoleBindUsers(false);
+    }
+    setDrawerVisible(true);
+    setCurrentRow(record);
+  }
+
+
+  return (
+    <PageContainer>
+      <ProTable
+        columns={columns}
+        request={getList}
+        actionRef={actionRef}
+        rowKey="roleId"
+        toolBarRender={() => [
+          <Button
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+            onClick={() => {
+              handleModalVisible(true);
+            }}
+          >
+            新增
+          </Button>,
+        ]}
+        pagination={{
+          pageSize: 10,
+        }}
+        search={{
+          defaultCollapsed: false,
+          labelWidth: 'auto',
+        }}
+      />
+
+      <ModalForm
+        title="新增角色"
+        width="800px"
+        labelCol={{ span: 5, offset: 3 }}
+        layout={'horizontal'}
+        visible={createModalVisible}
+        onVisibleChange={handleModalVisible}
+        modalProps={{
+          destroyOnClose:true
+        }}
+        onFinish={async (value) => {
+          const success = await addList(value);
+          //   console.log({ success });
+          if (success) {
+            handleModalVisible(false);
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+          return true;
+        }}
+      >
+        <ProFormText
+          label="角色名"
+          rules={[
+            {
+              required: true,
+              message: '角色名是必填项!',
+            },
+          ]}
+          width="sm"
+          name="roleName"
+        />
+        <ProFormText
+          label="备注"
+          rules={[
+            {
+              required: false,
+              message: '',
+            },
+          ]}
+          width="sm"
+          name="remark"
+        />
+      </ModalForm>
+
+      {/* 更新 */}
+      <UpdateForm
+        onSubmit={async (value) => {
+          // console.log({value});
+          const { roleId, roleName, remark } = value;
+          const success = await editList({ roleId, roleName, remark });
+
+          if (success) {
+            handleUpdateModalVisible(false);
+            setCurrentRow(undefined);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+          
+        }}
+        onCancel={() => {
+          handleUpdateModalVisible(false);
+          setCurrentRow(undefined);
+        }}
+        updateModalVisible={updateModalVisible}
+        updateModalVisibleChange={updateModalVisibleChange}
+        values={currentRow || {}}
+      />
+
+      {editRoleBindUsers ? (
+        //编辑用户
+        <DrawerContent
+          columns={DrawerTableUsersColumns}
+          visible={drawerVisible}
+          currentRow={currentRow}
+          title="绑定用户"
+          defaultSelected={selectedUsers}
+          onVisibleChange={(bool) => setDrawerVisible(bool)}
+          renderListFunc={getUsers}
+          config={{tableSearch:true}}
+          onFinishFunc={async (value, selectedRowKeys) => {
+            
+            const { roleId } = currentRow;
+            const resp = await roleBindUser({ roleId, userIds: selectedRowKeys });
+            const { status } = resp;
+            if (status == 200) {
+              setDrawerVisible(false);
+              setCurrentRow(undefined);
+              if (actionRef.current) {
+                actionRef.current.reload();
+              }
+            }
+          }}
+        />
+      ) : (
+        //编辑权限
+        <DrawerContent
+          columns={DrawerTableMenusColumns}
+          visible={drawerVisible}
+          currentRow={currentRow}
+          title="绑定权限"
+          defaultSelected={selectedMenus}
+          onVisibleChange={(bool) => setDrawerVisible(bool)}
+          renderListFunc={getMenus}
+          config={{rowKeys:'menuId',tableSearch:false}}
+          tableSearch={false}
+          onFinishFunc={async (value, selectedRowKeys) => {
+            console.log({value,selectedRowKeys});
+            // return ;
+            const { roleId } = currentRow;
+            const resp = await roleBindMenu({ roleId, menuIds: selectedRowKeys });
+            const { status } = resp;
+            if (status == 200) {
+              setDrawerVisible(false);
+              setCurrentRow(undefined);
+              if (actionRef.current) {
+                actionRef.current.reload();
+              }
+            }
+          }}
+        />
+      )}
+    </PageContainer>
+  );
+};
+
+export default UserMana;

+ 100 - 0
src/pages/PlatformMana/roleManage/service.js

@@ -0,0 +1,100 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:31
+ * @LastEditTime: 2021-09-28 09:52:04
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/service.js
+ */
+
+
+import { request } from 'umi';
+
+//获角色列表
+export async function getRoleList(params, options) {
+    return request('/api/pfm/role/list', {
+      method: 'GET',
+      params: {...params},
+      ...(options || {}),
+    });
+}
+
+//新增角色
+export async function addList(body, options) {
+    return request('/api/pfm/role/save', {
+      method: 'POST',
+      data: {...body},
+      ...(options || {}),
+    });
+}
+
+//编辑角色
+export async function editList(body, options) {
+  return request('/api/pfm/role/edit', {
+    method: 'POST',
+    data: {...body},
+    ...(options || {}),
+  });
+}
+
+//删除角色
+export async function delList(params, options) {
+  const {ids} = params;
+  return request(`/api/pfm/role/delete`, {
+    data:ids,
+    method: 'POST',
+    ...(options || {}),
+  });
+}
+
+// //根据角色查询已绑用户
+// export async function getUsersByRoleId(params, options) {
+//   const {roleId} = params;
+//   return request(`/api/costAccount/role/editUserRole`, {
+//     data:{roleId, userIds},
+//     method: 'POST',
+//     ...(options || {}),
+//   });
+// }
+
+//角色绑定用户
+export async function roleBindUser(params, options) {
+  const {roleId, userIds} = params;
+  return request(`/api/pfm/role/editUserRole`, {
+    data:{roleId, userIds},
+    method: 'POST',
+    ...(options || {}),
+  });
+}
+
+//角色绑定菜单
+export async function roleBindMenu(params, options) {
+  const {roleId, menuIds} = params;
+  return request(`/api/pfm/role/editRoleMenu`, {
+    data:{roleId, menuIds},
+    method: 'POST',
+    ...(options || {}),
+  });
+}
+
+
+//获取角色已绑定的用户
+export async function roleHasBindUsers(params, options) {
+  const {roleId} = params;
+  return request(`/api/pfm/role/roleUsers`, {
+    params:{roleId},
+    method: 'GET',
+    ...(options || {}),
+  });
+}
+
+
+//获取角色已绑定的菜单
+export async function roleHasBindMenus(params, options) {
+  const {roleId} = params;
+  return request(`/api/pfm/role/roleMenus`, {
+    params:{roleId},
+    method: 'GET',
+    ...(options || {}),
+  });
+}

+ 52 - 0
src/pages/PlatformMana/roleManage/updateForm.jsx

@@ -0,0 +1,52 @@
+import React from 'react';
+import {
+  ProFormText,
+  ModalForm,
+} from '@ant-design/pro-form';
+
+
+
+const UpdateForm = (props) => {
+  const { updateModalVisible, updateModalVisibleChange, values, onSubmit } = props;
+  return (
+    <>
+      {
+        JSON.stringify(values) !== '{}' && <ModalForm
+          title="编辑角色"
+          width="800px"
+          initialValues={{ ...values }}
+          labelCol={{ span: 3, offset: 3 }}
+          layout={'horizontal'}
+          visible={updateModalVisible}
+          onVisibleChange={(visible) => updateModalVisibleChange(visible)}
+          onFinish={(value) => onSubmit({ ...values, ...value })}
+        >
+          <ProFormText
+            label="角色名"
+            rules={[
+              {
+                required: true,
+                message: '角色名是必填项!',
+              },
+            ]}
+            width="sm"
+            name="roleName"
+          />
+          <ProFormText
+            label="备注"
+            rules={[
+              {
+                required: false,
+                message: '',
+              },
+            ]}
+            width="sm"
+            name="remark"
+          />
+        </ModalForm>
+      }
+    </>
+  );
+};
+
+export default UpdateForm;

+ 270 - 0
src/pages/PlatformMana/userMana/index.js

@@ -0,0 +1,270 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:13
+ * @LastEditTime: 2021-09-29 18:15:52
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/index.js
+ */
+
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, Popconfirm} from 'antd';
+import React, { useState, useRef} from 'react';
+import { useModel } from 'umi';
+import { PageContainer } from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import { ModalForm, ProFormText, ProFormSelect } from '@ant-design/pro-form';
+import UpdateForm from './updateForm';
+import CAUpload from '@/components/CAUpload';
+import { getUserList, addUser, editUser, delUser,importExcel } from './service';
+
+const UserMana = () => {
+  const columns = [
+    {
+      title: 'Id',
+      dataIndex: 'id',
+      key: 'id',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '姓名',
+      dataIndex: 'name',
+      key: 'name',
+      ellipsis: true,
+    },
+    {
+      title: '用户名',
+      dataIndex: 'account',
+      key: 'account',
+      hideInSearch: true,
+      ellipsis: true,
+    },
+    {
+      title: '在职状态',
+      dataIndex: 'hospitalStatus',
+      key: 'hospitalStatus',
+      hideInSearch: true,
+      ellipsis: true,
+      render: (_,record) => {return (<>{record.hospitalStatus == 1 ? '在职' : '离职'}</>)},
+    },
+    {
+      title:'操作',
+      dataIndex: 'option',
+      valueType: 'option',
+      render: (_, record) => [
+        <a
+          key="config"
+          onClick={() => {
+            handleUpdateModalVisible(true);
+            setCurrentRow(record);
+          }}
+        >
+          编辑
+        </a>,
+        <Popconfirm
+          key="subscribeAlert"
+          title="是否确定删除?"
+          onConfirm={() => {
+            setCurrentRow(record);
+            delUserHandler(record);
+          }}
+        >
+          <a>删除</a>
+        </Popconfirm>,
+      ],
+    },
+  ];
+
+  const [createModalVisible, handleModalVisible] = useState(false);
+  const [updateModalVisible, handleUpdateModalVisible] = useState(false);
+  const actionRef = useRef();
+  const [currentRow, setCurrentRow] = useState({});
+  const { initialState, setInitialState } = useModel('@@initialState');
+  const {currentUser:{token}} = initialState;
+  // const [shareParamsSetting,setShareParamsSetting] = useState(false);  //是否分摊参数设置
+
+
+  
+  /**
+   *
+   * @param {Boolean} bool 弹窗展示状态
+   */
+  const updateModalVisibleChange = (bool) => {
+    handleUpdateModalVisible(bool);
+    if (!bool) setCurrentRow(undefined);
+  };
+
+  //获取用户列表
+  const getUserlist = async (params = {}, sort, filter) => {
+    const res = await getUserList(params);
+    if(res){
+      return {
+        data: res.list,
+        total: res.totalCount,
+        success: true,
+      };
+    }
+  };
+
+  /**
+   *
+   * @param {Object} value 删除项数据
+   */
+  const delUserHandler = async (value) => {
+    const resp = await delUser(value);
+    if(resp){
+      if (actionRef.current) {
+        actionRef.current.reload();
+      }
+    }
+  };
+  //自定义上传回调
+  const customRequestCallback = async (formData)=>{
+    const resp = await importExcel({formData},{
+      'content-type':'multipart/form-data',
+    });
+    if(resp){
+      if (actionRef.current) {
+        actionRef.current.reload();
+      }
+    }
+  }
+
+  return (
+    <PageContainer>
+      <ProTable
+        columns={columns}
+        request={getUserlist}
+        actionRef={actionRef}
+        rowKey="id"
+        toolBarRender={() => [
+          <Button
+            key="button"
+            icon={<PlusOutlined />}
+            type="primary"
+            onClick={() => {
+              handleModalVisible(true);
+            }}
+          >
+            新增
+          </Button>,
+          <CAUpload  
+                templateHrefs={'/pfm/excel/getcurrentTemplate'}
+                url='/pfm/excel/importUser'
+                importSuccessCallback={() =>{}}
+                token={token}
+                type='normal'
+                customRequestCallback={customRequestCallback}
+          />
+        ]}
+        pagination={{
+          pageSize: 10,
+        }}
+        search={{
+          defaultCollapsed: false,
+          labelWidth: 'auto',
+        }}
+      />
+
+      <ModalForm
+        title="新增人员"
+        width="800px"
+        labelCol={{ span: 3, offset: 3 }}
+        layout={'horizontal'}
+        visible={createModalVisible}
+        onVisibleChange={handleModalVisible}
+        onFinish={async (value) => {
+          const success = await addUser(value);
+          //   console.log({ success });
+          if (success) {
+            handleModalVisible(false);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+        }}
+      >
+        <ProFormText
+          label="姓名"
+          rules={[
+            {
+              required: true,
+              message:'人员名是必填项',
+            },
+          ]}
+          width="sm"
+          name="name"
+        />
+        <ProFormText
+          label="账户"
+          rules={[
+            {
+              required: true,
+              message:'账户名是必填项',
+            },
+          ]}
+          width="sm"
+          name="account"
+        />
+        <ProFormText
+          label="密码"
+          rules={[
+            {
+              required: false,
+              message:'',
+            },
+          ]}
+          width="sm"
+          name="password"
+          placeholder='密码不修改留空'
+        />
+        <ProFormSelect
+          options={[
+            {
+              value: 0,
+              label: '离职',
+            },
+            {
+              value: 1,
+              label: '在职',
+            },
+          ]}
+          width="sm"
+          name="hospitalStatus"
+          label="在职状态"
+        />
+      </ModalForm>
+
+    
+      {/* 更新 */}
+      <UpdateForm
+        onSubmit={async (value) => {
+          // console.log({value});
+          const success = await editUser(value);
+
+          if (success) {
+            handleUpdateModalVisible(false);
+            setCurrentRow(undefined);
+
+            if (actionRef.current) {
+              actionRef.current.reload();
+            }
+          }
+        }}
+        onCancel={() => {
+          handleUpdateModalVisible(false);
+          setCurrentRow(undefined);
+        }}
+        updateModalVisible={updateModalVisible}
+        updateModalVisibleChange={updateModalVisibleChange}
+        values={currentRow || {}}
+      />
+
+
+    </PageContainer>
+  );
+};
+
+export default UserMana;

+ 60 - 0
src/pages/PlatformMana/userMana/service.js

@@ -0,0 +1,60 @@
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 10:13:31
+ * @LastEditTime: 2021-09-28 09:52:28
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/pages/UserMana/service.js
+ */
+
+
+import { request } from 'umi';
+
+//获用户列表
+export async function getUserList(params, options) {
+    return request('/api/pfm/user/list', {
+      method: 'GET',
+      params: {...params},
+      ...(options || {}),
+    });
+}
+
+//新增人员
+export async function addUser(body, options) {
+    return request('/api/pfm/user/save', {
+      method: 'POST',
+      data: {...body},
+      ...(options || {}),
+    });
+}
+
+//编辑人员
+export async function editUser(body, options) {
+  return request('/api/pfm/user/update', {
+    method: 'POST',
+    data: {...body},
+    ...(options || {}),
+  });
+}
+
+//删除人员
+export async function delUser(params, options) {
+  const {id} = params;
+  const ids = [id];
+  return request(`/api/pfm/user/delete`, {
+    data:ids,
+    method: 'POST',
+    ...(options || {}),
+  });
+}
+
+
+//导入excel
+export async function importExcel(body, options) {
+  const {formData} = body;
+  return request('/api/pfm/excel/importUser', {
+    method: 'POST',
+    data:formData,
+    ...(options || {}),
+  });
+}

+ 81 - 0
src/pages/PlatformMana/userMana/updateForm.jsx

@@ -0,0 +1,81 @@
+import React from 'react';
+import {
+    ProFormSelect,
+    ProFormText,
+    ModalForm,
+} from '@ant-design/pro-form';
+
+
+
+const UpdateForm = (props) => {
+    const {updateModalVisible,updateModalVisibleChange,values,onSubmit} = props;
+    // console.log({values});
+    return (
+        <>
+           {
+               JSON.stringify(values) !== '{}'&&<ModalForm
+               title="编辑人员"
+               width="800px"
+               initialValues={{...values}}
+               labelCol={{ span: 3, offset: 3 }}
+               layout={'horizontal'}
+               visible={updateModalVisible}
+               onVisibleChange={(visible)=>updateModalVisibleChange(visible)}
+               onFinish={(value)=>onSubmit({...values,...value})}
+             >
+               <ProFormText
+                 label="姓名"
+                 rules={[
+                   {
+                     required: true,
+                     message:'人员名是必填项',
+                   },
+                 ]}
+                 width="sm"
+                 name="name"
+               />
+               <ProFormText
+                 label="账户"
+                 rules={[
+                   {
+                     required: true,
+                     message:'账户名是必填项',
+                   },
+                 ]}
+                 width="sm"
+                 name="account"
+               />
+               <ProFormText
+                 label="密码"
+                 rules={[
+                   {
+                     required: false,
+                     message:'密码是必填项',
+                   },
+                 ]}
+                 placeholder="密码不修改时留空"
+                 width="sm"
+                 name="password"
+               />
+               <ProFormSelect
+                 options={[
+                   {
+                     value: 0,
+                     label: '离职',
+                   },
+                   {
+                     value: 1,
+                     label: '在职',
+                   },
+                 ]}
+                 width="sm"
+                 name="hospitalStatus"
+                 label="在职状态"
+               />
+             </ModalForm>
+           }
+        </>
+    );
+};
+
+export default UpdateForm;

+ 2 - 1
src/pages/user/Login/index.tsx

@@ -48,7 +48,7 @@ const Login: React.FC = () => {
       //医院标识
       let hospSign:any='';
       if(history){
-        hospSign = history.location.query?.hospSign
+        hospSign = history.location.query?.hospSign;
       }
    
       let loginResult = await login({ ...values,hospSign});
@@ -57,6 +57,7 @@ const Login: React.FC = () => {
         const defaultLoginSuccessMessage = '登录成功!';
         message.success(defaultLoginSuccessMessage);
         await setUserInfo({...loginResult});
+        localStorage.setItem('hospSign',hospSign); //保存医院标识
         /** 此方法会跳转到 redirect 参数所在的位置 */
         if (!history) return;
         const { query } = history.location;

+ 524 - 0
src/test.html

@@ -0,0 +1,524 @@
+<!--
+ * @Author: your name
+ * @Date: 2021-09-28 15:46:22
+ * @LastEditTime: 2021-09-28 15:46:22
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/test.html
+-->
+
+
+<html>
+<head>
+    <title>&#38382;&#39064;&#27719;&#24635;</title>
+    <meta http-equiv="X-UA-Compatible" content="chrome=1">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta name="author" content="FineReport"/>
+    <meta name="Copyright" content="FineReport"/>
+    <meta name="description" content="FineReport--Web Reporting Tool"/>
+    <meta name="keywords" content="FineReport,Web Reporting Tool"/>
+    <link rel="stylesheet" type="text/css"
+          href="http://112.124.59.133:8804/webroot/decision/view/form?op=emb&resource=finereport.css&cssVersion=1631787909766"/>
+    <link rel="stylesheet" type="text/css"
+          href="http://112.124.59.133:8804/webroot/decision/view/form?op=emb&resource=toolbar.css&cssVersion=1631787909766"/>
+    <!--插件引入的css文件-->
+
+
+    <script type="text/javascript">
+        window.initialWindowWidth = 600;
+        window.initialWindowHeight = 600;
+    </script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=emb&resource=finereport.js&inter=zh_CN&__v__=2021.01.25.11.03.31.957&jsVersion=1631787909766"></script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=emb&resource=finereport.chart.js&jsVersion=1631787909766"></script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=resource&resource=/com/fr/web/core/js/socket.io.js"></script>
+    <!--插件引入的js文件-->
+
+
+    <style type="text/css">
+        body.dragging, body.dragging * {
+            cursor: move !important;
+        }
+
+        .dragged {
+            position: absolute;
+            opacity: 1;
+            z-index: 2000;
+        }
+
+        #paramsTemplatePane > div {
+            display: inline;
+        }
+    </style>
+
+
+    <script type="text/javascript">
+
+    </script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=resource&resource=/com/fr/plugin/cloud/front/dist/polyfill.min.js"></script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=resource&resource=/com/fr/plugin/cloud/front/dist/fp.min.js"></script>
+    <script type="text/javascript"
+            src="http://112.124.59.133:8804/webroot/decision/view/form?op=resource&resource=/com/fr/plugin/cloud/front/fine.mark.init.js"></script>
+
+
+    <script type="text/javascript">
+        //ie下低版本时修改浏览器渲染模式
+        if ($.browser.msie && $.browser.version <= 8.0) {
+            $("meta[http-equiv='X-UA-Compatible']").attr("content", "IE=5, IE=EmulateIE7, chrome=1");
+        }
+        $(function () {
+            var $body = $('body');
+            $('<form class="form-submit"></form>').attr('name', '&#38382;&#39064;&#27719;&#24635;').appendTo($body);
+
+            var items = [];
+            var scrollHeight = 6;
+            var expandHeight = 8;
+            var contenConfig = {
+                "type": "border",
+                "widgetName": "FORM",
+                "disabled": false,
+                "invisible": false,
+                "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=form&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                "useBookMark": false,
+                "bookMarkName": "",
+                "vgap": 0,
+                "hgap": 0,
+                "compInterval": 0,
+                "scrollable": false,
+                "items": [{
+                    "region": "center",
+                    "el": {
+                        "type": "horizontal",
+                        "disabled": false,
+                        "invisible": false,
+                        "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=null&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                        "useBookMark": false,
+                        "bookMarkName": "",
+                        "vgap": 0,
+                        "hgap": 0,
+                        "compInterval": 0,
+                        "scrollable": false,
+                        "items": [],
+                        "showBookmarks": false,
+                        "alignment": "center",
+                        "displayposition": 0
+                    }
+                }],
+                "showBookmarks": false,
+                "__FIT__": false,
+                "__FITSTATE__": 0,
+                "refresh": false
+            };
+            var paraConfig = {
+                "type": "parameter",
+                "widgetName": "PARA",
+                "disabled": false,
+                "invisible": false,
+                "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=para&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                "useBookMark": false,
+                "bookMarkName": "",
+                "widgetBackground": "",
+                "vgap": 0,
+                "hgap": 0,
+                "compInterval": 0,
+                "scrollable": false,
+                "items": [{
+                    "type": "datetime",
+                    "widgetName": "开始时间",
+                    "disabled": false,
+                    "invisible": false,
+                    "needSubmit": true,
+                    "value": {"date_milliseconds": 1630425600000},
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=开始时间&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "labelName": "选择时间",
+                    "useBookMark": false,
+                    "bookMarkName": "dateEditor0",
+                    "fontSize": 12,
+                    "directEdit": true,
+                    "format": "yyyy-MM-dd",
+                    "x": 367,
+                    "y": 28,
+                    "width": 110,
+                    "height": 21
+                }, {
+                    "type": "datetime",
+                    "widgetName": "结束时间",
+                    "disabled": false,
+                    "invisible": false,
+                    "needSubmit": true,
+                    "value": {"date_milliseconds": 1632931200000},
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=结束时间&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "labelName": "情境名称",
+                    "useBookMark": false,
+                    "bookMarkName": "dateEditor1",
+                    "fontSize": 12,
+                    "directEdit": true,
+                    "format": "yyyy-MM-dd",
+                    "x": 494,
+                    "y": 28,
+                    "width": 110,
+                    "height": 21
+                }, {
+                    "type": "formsubmit",
+                    "widgetName": "BUTTON0",
+                    "disabled": false,
+                    "invisible": false,
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=button0&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "listeners": [{
+                        "eventName": "click", "once": false, "action": function (e) {
+                            var as = arguments;
+                            return FR.tc(function () {
+                                ;
+                                return eval("(function(){try{this.setEnable(false);\n}catch(ex){FR.Logger.error(ex);FR.Msg.toast(FR.i18nText('Custom')+'JS'+FR.i18nText('Error')+' : '+ex.message);}}).createDelegate(this, [], 0).apply(this, arguments)");
+                            }, this, as)
+                        }
+                    }, {
+                        "eventName": "click", "once": false, "action": function (e) {
+                            var as = arguments;
+                            return FR.tc(function () {
+                                ;
+                                return eval("(function(){try{if(this.options.form!=null&&$.isFunction(this.options.form.formSubmit)){this.options.form.QueryBtn=this;var self=this;this.options.form.formSubmit({url:\"/webroot/decision/view/form?op=fr_dialog&cmd=parameters_d&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068\",asyn:true,callback:function(){_g().once(\"afterload\",function(){self.enable()});_g().loadContentPane()}})};\n}catch(ex){FR.Logger.error(ex);FR.Msg.toast(FR.i18nText('Custom')+'JS'+FR.i18nText('Error')+' : '+ex.message);}}).createDelegate(this, [], 0).apply(this, arguments)");
+                            }, this, as)
+                        }
+                    }],
+                    "useBookMark": false,
+                    "bookMarkName": "button0",
+                    "render": true,
+                    "text": "查询",
+                    "hotkeys": "enter",
+                    "isToggle": false,
+                    "key": "formsubmit",
+                    "x": 647,
+                    "y": 28,
+                    "width": 80,
+                    "height": 21
+                }, {
+                    "type": "combo",
+                    "widgetName": "COMBOBOX0",
+                    "disabled": false,
+                    "invisible": false,
+                    "needSubmit": true,
+                    "value": "",
+                    "Databinding": {},
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=comboBox0&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "labelName": "情境名称",
+                    "useBookMark": false,
+                    "bookMarkName": "comboBox0",
+                    "fontSize": 12,
+                    "directEdit": true,
+                    "norepeat": true,
+                    "searchTime": 200,
+                    "customData": true,
+                    "autoMode": true,
+                    "mode": "remote",
+                    "controlAttr": {"value": ""},
+                    "x": 124,
+                    "y": 28,
+                    "width": 108,
+                    "height": 21
+                }, {
+                    "type": "label",
+                    "widgetName": "LABEL0",
+                    "disabled": false,
+                    "invisible": false,
+                    "needSubmit": true,
+                    "value": "情境名称",
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=label0&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "useBookMark": false,
+                    "bookMarkName": "label0",
+                    "verticalcenter": true,
+                    "textalign": "center",
+                    "decoration": "none",
+                    "color": "rgb(0,0,0)",
+                    "textColor": "0.0,0.0,0.0,1.0,",
+                    "fontsize": 12,
+                    "fontfamily": "PingFang SC",
+                    "wrap": true,
+                    "autoline": true,
+                    "x": 32,
+                    "y": 28,
+                    "width": 80,
+                    "height": 21
+                }, {
+                    "type": "label",
+                    "widgetName": "LABEL0_C",
+                    "disabled": false,
+                    "invisible": false,
+                    "needSubmit": true,
+                    "value": "选择时间",
+                    "widgetUrl": "http://112.124.59.133:8804/webroot/decision/view/form?op=widget&widgetname=label0_c&sessionID=e63cf0fa-bf6e-4923-bfd6-af680379b068",
+                    "useBookMark": false,
+                    "bookMarkName": "label0",
+                    "verticalcenter": true,
+                    "textalign": "center",
+                    "decoration": "none",
+                    "color": "rgb(0,0,0)",
+                    "textColor": "0.0,0.0,0.0,1.0,",
+                    "fontsize": 12,
+                    "fontfamily": "PingFang SC",
+                    "wrap": true,
+                    "autoline": true,
+                    "x": 274,
+                    "y": 28,
+                    "width": 80,
+                    "height": 21
+                }],
+                "showBookmarks": false,
+                "itemsIndex": ["COMBOBOX0", "开始时间", "结束时间", "BUTTON0"],
+                "stickyItemsIndex": [],
+                "absoluteCompState": 0,
+                "absoluteResolutionScaleW": 1.0,
+                "absoluteResolutionScaleH": 1.0,
+                "hasResize": false,
+                "paraDisplay": true,
+                "delayDisplayContent": true,
+                "useParamsTemplate": true,
+                "position": "left",
+                "width": 960,
+                "parambg": {},
+                "height": 65
+            };
+
+            var contentContainer = $("<div class='content-container'>");
+            var delayDisplay = paraConfig['delayDisplayContent'];
+
+            contenConfig.renderEl = contentContainer;
+            form = new FR.contentForm(contenConfig);
+            FR.SessionMgr.register("e63cf0fa-bf6e-4923-bfd6-af680379b068", form);
+
+            items.push({
+                region: 'center',
+                el: contentContainer
+            });
+
+            window.globalForm = form;
+            var barHeight = paraConfig.width > document.body.offsetWidth ? scrollHeight : 0;
+            FR.$defaultImport('/com/fr/web/core/js/paramtemplate.js', 'js');
+            var paramstemplateHeight = 30;
+            var north = {
+                region: 'north',
+                height: paramstemplateHeight,
+                el: {
+                    type: 'border',
+                    widgetName: 'paramsTemplate',
+                    items: [
+                        {
+                            region: 'east',
+                            width: 138,
+                            el: {
+                                type: 'horizontal',
+                                alignment: 'right',
+                                items: [{
+                                    el: {
+                                        type: 'button',
+                                        widgetName: 'saveBtn',
+                                        text: FR.i18nText("Fine-Engine_Report_Designer_Save_As_Params_Template")
+                                    }, width: 128
+                                }]
+                            }
+                        }, {
+                            region: 'center',
+                            el: {
+                                type: 'horizontal',
+                                widgetName: 'paramsTemplatePane',
+                                width: paraConfig.width - 120,
+                                minWidth: paraConfig.width - 120,
+                                alignment: 'left',
+                                items: []
+                            }
+                        }, {
+                            region: 'west',
+                            width: 30,
+                            el: {
+                                type: 'horizontal',
+                                alignment: 'left',
+                                items: [
+                                    {
+                                        el: {
+                                            type: 'iconbutton',
+                                            widgetName: 'newParamsBtn',
+                                            width: 30,
+                                            baseClass: 'fs-new-params-template-blue'
+                                        },
+                                        width: 30
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                }
+            };
+            var paramsTemplate = getParamsTemplate(form.sessionID);
+            if (!paraConfig.useParamsTemplate || FR.isEmpty(paramsTemplate)) {
+                paramstemplateHeight = 0;
+                north = {};
+            }
+            if (!$.isEmptyObject(paraConfig)) {
+                var paraContainer = $("<div class='para-container' style='overflow: auto;'>");
+                var alignLayoutName = '__layout4align__';
+                paraContainer.height(paraConfig.height + expandHeight + barHeight + paramstemplateHeight);
+                var $expandEl = $("<div class='parameter-container-collapseimg-up' style='cursor: pointer'></div>");
+                bindParaCollapse($expandEl);
+                var $center = $('<div class="pmeter-container"></div>');
+                var south = {
+                    region: 'south', height: expandHeight, el: {
+                        type: 'horizontal',
+                        items: [
+                            {el: $expandEl, width: 120}
+                        ]
+                    }
+                };
+                var center = {
+                    region: 'center',
+                    el: {
+                        type: 'horizontal',
+                        widgetName: alignLayoutName,
+                        alignment: paraConfig.position,
+                        items: [
+                            {el: $center, width: paraConfig.width}
+                        ]
+                    }
+                };
+                var itemlst = [north, south, center];
+                var pCon = {
+                    renderEl: paraContainer,
+                    type: 'border',
+                    items: itemlst
+                };
+                //有个默认的背景
+                var bg = FR.isEmptyObj(paraConfig.parambg) ? {background: '#f7f8fa'} : paraConfig.parambg;
+                FR.setBackground(paraContainer, bg);
+                paraConfig.renderEl = $center;
+                window.globalForm.parameterEl = new FR.contentForm(paraConfig);
+                items.push({
+                    region: 'north',
+                    el: pCon
+                });
+            }
+
+            /**
+             * 判断尺寸,在尺寸为0的情况下返回一个默认值
+             * 在某些情况下,如平台快速点击多个报表时,无法获取到尺寸,
+             * 提供一个默认值,
+             *
+             * @param length    默认尺寸
+             * @param defaultValue  默认值
+             * @returns {*}
+             */
+            function checkSizeOrDefault(length, defaultValue) {
+                if (isNaN(defaultValue)) {
+                    return length;
+                }
+                return length === 0 ? defaultValue : length;
+            }
+
+            var width = checkSizeOrDefault(FR.windowWidth, window.location.href.getQuery("width"));
+            var height = checkSizeOrDefault(FR.windowHeight, window.location.href.getQuery("height"));
+            var borderLayout = new FR.BorderLayout({
+                items: items,
+                renderEl: $body,
+                width: width,
+                height: height
+            });
+
+
+            //给参数界面添加横向滚动条
+            var showParamsTemplate = paraConfig.useParamsTemplate && paramsTemplate !== null;
+            addScollBar(paraContainer, $center, paraConfig.height + (showParamsTemplate ? 30 : 0), scrollHeight);
+            borderLayout.doLayout();
+
+            $('[widgetname^=sortable]').removeAttr('style');
+            initParameterTemplate(paraConfig, paraConfig.items, form.sessionID, borderLayout, paramsTemplate);
+
+
+            $(window).resize(function () {
+                borderLayout.element.bounds({
+                    'width': FR.windowWidth,
+                    'height': FR.windowHeight
+                });
+                if (!form.scaleProcess(borderLayout, width, height)) {
+                    addScollBar(paraContainer, $center, paraConfig.height + (showParamsTemplate ? 30 : 0), scrollHeight);
+                    borderLayout.doLayout();
+                    $('[widgetname^=sortable]').removeAttr('style');
+                }
+                width = FR.windowWidth;
+                height = FR.windowHeight;
+            });
+            // 整个form都doLayout一下
+            var browser = $.browser;
+            //b:for chrome,find reason
+            if (browser.safari && browser.webkit || browser.msie && browser.version < 7) {
+                $(window).trigger("resize");
+                $body.css('overflow', 'auto');
+            }
+            // FR.Layout 有this.element.css("overflow","hidden");
+            //放大后再缩小, body和contentContainer大小一致, 却出现了滚动条, 很难看.
+            contentContainer.css('overflow', 'auto');
+
+            if (!delayDisplay) {
+                form.parameterCommit();
+            }
+
+            function addScollBar(container, mover, top, height) {
+                if (container) {
+                    container.hScrollPane({
+                        mover: mover, //指定container对象下的哪个元素需要滚动位置 | 必传项;
+                        showArrow: false, //指定是否显示左右箭头,默认不显示 | 可选项;
+                        top: top, //滚动条所在的top位置
+                        height: height,//滚动条的高度
+                        //moverW:function(){return $(".press").width();}(), //传入水平滚动对象的长度值,不传入的话默认直接获取mover的宽度值 | 可选项;
+                        //handleMinWidth:100,//指定handle的最小宽度,要固定handle的宽度请在css中设定handle的width属性(如 width:28px!important;),不传入则不设定最小宽度 | 可选项;
+                        //dragable:true, //指定是否要支持拖动效果,默认可以拖动 | 可选项;
+                        easing: false, //滚动是否需要滑动效果,默认有滑动效果 | 可选项;
+                        // handleCssAlter:"draghandlealter", //指定拖动鼠标时滚动条的样式,不传入该参数则没有变化效果 | 可选项;
+                        mousewheel: {bind: false, moveLength: 500} //mousewheel: bind->'true',绑定mousewheel事件; ->'false',不绑定mousewheel事件;moveLength是指定鼠标滚动一次移动的距离,默认值:{bind:true,moveLength:300} | 可选项;
+                    });
+                }
+            }
+
+            function bindParaCollapse($element) {
+                $element.click(function () {
+                    var resizeTime = new Date();
+                    var self = this;
+                    self.lastResizeTime = resizeTime;
+                    setTimeout(function () {
+                        if (resizeTime === self.lastResizeTime) {
+                            self.lastResizeTime = null;    // REPORT-4620,这里使用delete在IE8以下会有bug
+                            paraContainer.animate({
+                                height: (self.hasCollapsed ? "+=" : "-=") + (paraConfig.height + barHeight + paramstemplateHeight)
+                            }, "fast", function () {
+                                var height = paraContainer.height();
+                                self.hasCollapsed = !self.hasCollapsed;
+                                $expandEl.switchClass('parameter-container-collapseimg-down', 'parameter-container-collapseimg-up');
+                                borderLayout.getWidgetByName(alignLayoutName).setVisible(!self.hasCollapsed);
+                                if (borderLayout.getWidgetByName('paramsTemplatePane') !== undefined) {
+                                    borderLayout.getWidgetByName('paramsTemplatePane').setVisible(!self.hasCollapsed);
+                                    borderLayout.getWidgetByName('saveBtn').setVisible(!self.hasCollapsed);
+                                    borderLayout.getWidgetByName('newParamsBtn').setVisible(!self.hasCollapsed);
+                                }
+                                borderLayout.regionField.center.el = $('.content-container');
+                                borderLayout.setRegionWH('north', height);
+                                borderLayout.doLayout();
+                                form.fireEvent(FR.Events.PARACOLLAPSE);
+                                if (FR.Form.bindFitResize && FR.Browser.isIE8Before()) {
+                                    form.loadContentPane(true);
+                                }
+                                $('[widgetname^=sortable]').removeAttr('style');
+                            });
+                        }
+                    }, 222);
+                });
+            }
+
+        })
+    </script>
+    <script type="text/javascript">
+    </script>
+</head>
+<body style="height:100%; width:100%; overflow:auto">
+</body>
+</html>

+ 143 - 0
src/utils.js

@@ -0,0 +1,143 @@
+/*
+ * @Author: your name
+ * @Date: 2021-09-26 17:59:56
+ * @LastEditTime: 2021-09-29 13:55:59
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /MedicalWisdomCheckSys/src/pages/utils.js
+ */
+
+
+
+/*
+ * @Author: your name
+ * @Date: 2021-07-26 13:50:44
+ * @LastEditTime: 2021-08-27 14:31:46
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: /TracerMethodology_PC/src/utils.js
+ */
+
+
+//获取url参数
+/**
+ * 
+ * @param {*} name 需要获取的query名
+ * @returns 
+ */
+
+
+ import { useRequest,request,history } from 'umi';
+ import { stringify } from 'querystring';
+
+
+
+const getQueryString = (name)=>{
+    let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
+    let r = window.location.search.substr(1).match(reg);
+ 
+    if (r != null) {
+        return decodeURIComponent(r[2]);
+    };
+    return null;
+} 
+
+
+  /**
+ * 退出登录,并且将当前的 url 保存
+ */
+   const loginOut = async () => {
+
+    const { query = {}, pathname } = history.location;
+    const { redirect } = query;
+    const hospSign = localStorage.getItem('hospSign');
+  
+    if (window.location.pathname !== '/user/login' && !redirect) {
+      history.replace({
+        pathname: '/user/login',
+        search: stringify({
+          redirect:pathname,
+          hospSign:hospSign
+        }),
+      });
+      localStorage.removeItem('hospSign');
+    }
+  };
+
+
+
+/**
+ * 
+ * @param {Function} requestFunc request函数
+ */
+const CARequest = (url)=>{
+      const { data, error, loading } = useRequest(() => {
+        return request(url);
+      });
+      console.log({data, error, loading});
+      
+}
+
+//递归获取所有层级某一属性
+const deepGetVal = (dataToDeep,key,subArr)=>{
+    // console.log({dataToDeep,key,subArr});
+    let resultArr = [];
+    
+    function looper(dataToDeep,key,subArr){
+        dataToDeep.forEach(item=>{
+            if(item[subArr]&&item[subArr].length>0){
+                resultArr.push(item[key]);
+                looper(item[subArr],key,subArr);
+            }else {
+                resultArr.push(item[key]);
+            }
+        });
+    }
+    looper(dataToDeep,key,subArr);
+
+    return resultArr
+}
+
+//递归获取所有有树子集的节点
+const deepGetAllParents = (dataToDeep,subArr)=>{
+    let resultArr = [];
+
+    function looper(dataToDeep,subArr){
+        dataToDeep.forEach(item=>{
+            if(item[subArr]&&item[subArr].length>0){
+                resultArr.push(item);
+                // console.log({resultArr});
+                looper(item[subArr],subArr);
+            }
+        });
+    };
+
+    looper(dataToDeep,subArr);
+
+    return resultArr
+    
+}
+
+//数组去重
+function unique(arr) {
+    if (!Array.isArray(arr)) {
+        console.log('type error!')
+        return
+    }
+    var array = [];
+    for (var i = 0; i < arr.length; i++) {
+        if (array .indexOf(arr[i]) === -1) {
+            array .push(arr[i])
+        }
+    }
+    return array;
+}
+
+export  {
+    getQueryString,
+    CARequest,
+    deepGetVal,
+    deepGetAllParents,
+    unique,
+    loginOut
+}