code4eat před 7 měsíci
rodič
revize
c5b1edbc70

+ 1 - 2
config/config.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2022-01-07 10:04:20
- * @LastEditTime: 2024-12-03 11:09:39
+ * @LastEditTime: 2024-12-10 16:44:01
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/config/config.ts
@@ -151,7 +151,6 @@ export default defineConfig({
           component: './noAccess',
         },
         {
-          title: '精益管管理中台',
           path: '/platform',
           component: '@/pages/platform/_layout.tsx',
           routes: [

+ 2 - 1
config/proxy.ts

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2024-04-09 18:07:34
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2024-10-25 09:34:46
+ * @LastEditTime: 2024-12-19 10:48:03
  * @FilePath: /KC-MiddlePlatform/config/proxy.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -14,6 +14,7 @@ const proxy: { [key: string]: any } = {
     '/gateway': {
       //target: 'http://47.96.149.190:5000',
       target: 'http://120.27.235.181:5000',
+      // target: 'http://platform.pre.bs.qjczt.com:5000',
       changeOrigin: true,
       // pathRewrite: { '^/master': '' },
     },

+ 0 - 0
public/favicon.ico → public/w.ico


+ 50 - 31
src/app.tsx

@@ -7,10 +7,11 @@ import { UserDataType, getQiankunMicroApps } from '@/service/login';
 
 import { BasicLayoutProps } from '@ant-design/pro-layout';
 import { logoutHandle } from './global';
-import { Platforms } from './constant';
+import { KcimCenterSysId, Platforms } from './constant';
 import { SpacicalPageParamsType } from './typings';
 import { createFromIconfontCN } from '@ant-design/icons';
-import { handleLogin } from './pages/login';
+import { changeFavicon, getHospType, handleLogin } from './pages/login';
+import { getSysParamsByCode } from './service';
 
 
 window.isParentApp = true;
@@ -39,18 +40,22 @@ export const initialStateConfig = {
 type InitialStateType = {
   navData: any[];
   menuData: any[],//中台菜单
+  customerType: string, //客户类型
   userData?: UserDataType;
   systemLists?: TopBar.Tab[]; //当前医院可选子系统列表
   openedSysLists?: TopBar.Tab[]; //当前已打开的系统列表
   currentSelectedSys?: TopBar.Tab; //当前选中的tab
   logout?: () => Promise<boolean>;
   childAppIsShowMenu?: boolean;
+  pageTitle:string,
   spacicalPageParamsType?: SpacicalPageParamsType[];
   getHospSubSystemListFunc?: () => Promise<any[]>;
 };
 
 
-export async function getInitialState(): Promise<InitialStateType> {
+
+
+export async function getInitialState(): Promise<InitialStateType> {  
 
   const fetchUserInfo = async () => {
     try {
@@ -99,10 +104,6 @@ export async function getInitialState(): Promise<InitialStateType> {
     return undefined;
   };
 
-  const getAppIcon = (name: string) => {
-    return Platforms.filter((i) => i.name == name).length > 0 ? Platforms.filter((i) => i.name == name)[0].logo : '';
-  };
-
   //获取当前账号所有子应用列表
   const getHospSubSystemListFunc = async () => {
     // const data = await getHospSubSystemList();
@@ -120,9 +121,14 @@ export async function getInitialState(): Promise<InitialStateType> {
 
 
   const logout = logoutHandle;
-
   const userData = await fetchUserInfo();
 
+  let customerType = undefined;
+  
+  if (userData?.token) {
+    customerType = await getHospType();
+  }
+
   let systemLists: userRelationInfo.OwnAppsItem[] = [];
   // let navData:any[] = [];
   if (userData) {
@@ -134,7 +140,14 @@ export async function getInitialState(): Promise<InitialStateType> {
 
   const localInitData = localStorage.getItem('initialState');
   const currentSelectedTab = localStorage.getItem('currentSelectedTab');
+  const { loginPic } = JSON.parse(localStorage.getItem('currentSelectedSubHop') as string);
 
+  if (loginPic.length > 0) {
+    const arr = loginPic.split('|');
+    if (arr.length == 2) {
+      changeFavicon(arr[1]);
+    }
+  }
 
   return {
     currentSelectedSys: currentSelectedTab != null ? JSON.parse(currentSelectedTab) : undefined,
@@ -142,7 +155,9 @@ export async function getInitialState(): Promise<InitialStateType> {
     ...JSON.parse(localInitData ? localInitData : '{}'), //覆盖,恢复tab状态
     userData,
     logout,
+    pageTitle:'欢迎进入医管平台',
     favicon: '',
+    customerType,
     spacicalPageParamsType: [],
     getHospSubSystemListFunc,
     systemLists: systemLists,
@@ -348,33 +363,33 @@ export const qiankun = async () => {
         //   //entry: '//localhost:8804',  //本地调试
         //   //entry: '//198.198.203.161:5000/pfmview/', //淮南
         // },
-        {
-          name: 'budgetManaSystem', // 唯一 id
-          //entry: '//localhost:8002',
-          entry: '//120.27.235.181:5000/perform/',  //开发
-          //entry: '//47.96.149.190:5000/perform/', //演示
-          //entry: '//198.198.203.161:5000/perform/', //淮南
-        },
+        // {
+        //   name: 'budgetManaSystem', // 唯一 id
+        //   // entry: '//localhost:8002',
+        //   //entry: '//120.27.235.181:5000/perform/',  //开发
+        //   //entry: '//47.96.149.190:5000/perform/', //演示
+        //   //entry: '//198.198.203.161:5000/perform/', //淮南
+        // },
         // {
         //   name: 'pfmBackMana', // 唯一 id
         //   entry: '//localhost:8001'
         //   //entry: '//120.27.235.181:5000/pfmManager/', // 开发
         // },
-        {
-          name: 'CostAccountingSys', // 唯一 id
-          entry: '//localhost:8002',
-          //entry: '//120.27.235.181:5000/costAccount/', // 开发
-        },
+        // {
+        //   name: 'CostAccountingSys', // 唯一 id
+        //   entry: '//localhost:8002',
+        //   //entry: '//120.27.235.181:5000/costAccount/', // 开发
+        // },
         {
           name: 'MediResourceManaSys', // 唯一 id
           entry: '//localhost:8001',
           //entry: '//120.27.235.181:5000/costAccount/', // 开发
         },
-        {
-          name: 'MedicalWisdomCheckSys', // 唯一 id
-          entry: '//localhost:8804',
-          //entry: '//120.27.235.181:5000/pfmview/', // 开发
-        },
+        // {
+        //   name: 'MedicalWisdomCheckSys', // 唯一 id
+        //   entry: '//localhost:8804',
+        //   //entry: '//120.27.235.181:5000/pfmview/', // 开发
+        // },
         // {
         //   name: 'personnelManaSystem', // 唯一 id
         //   entry: '//192.168.0.118:8005'
@@ -460,18 +475,22 @@ export function patchRoutes({ routes }: { routes: any }) {
   treeLoop(routes[0]);
 }
 
-export const layout = ({ initialState: { } }: { initialState: InitialStateType }): BasicLayoutProps => {
+export const layout = ({
+  initialState,
+}: {
+  initialState?: InitialStateType;
+}): BasicLayoutProps => {
+  const { navData = [], menuData = [], customerType = '' } = initialState || {};
+
   return {
     headerRender: false,
     rightContentRender: () => <>right</>,
     footerRender: () => null,
     onPageChange: () => {
-      // //如果没有登录,重定向到 login
-      // if (!userData && location.pathname !== '/login') {
-      //   // history.push('/login');
-      // }
+      // 页面变化时的逻辑
     },
     menuHeaderRender: undefined,
-    // ...initialState?.settings,
   };
 };
+
+

+ 150 - 107
src/components/NavSelecter/index.tsx

@@ -1,16 +1,8 @@
-/*
- * @Author: code4eat awesomedema@gmail.com
- * @Date: 2022-06-29 11:05:04
- * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2024-01-16 16:37:52
- * @FilePath: /KC-MiddlePlatform/src/components/NavSelecter/index.tsx
- * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
- */
-
 import { Tabs, Checkbox, Button, message } from 'antd';
 import React, { Key, useEffect, useState } from 'react';
 import './style.less';
 import { findNodesBySomes, getLeafNodes } from '@/utils';
+import { CheckboxChangeEvent } from 'antd/lib/checkbox';
 
 const { TabPane } = Tabs;
 
@@ -33,152 +25,203 @@ export type NavSelecterData = {
   child?: NavSelecterData[];
 };
 
-export interface NavSelecter {
+export interface NavSelecterProps {
   onVisibleChange?: (t: boolean) => void;
   onChecked?: (t: NavSelecterItemType[]) => void;
   value?: Key[];
   data?: NavSelecterData[];
   title?: string;
-  type?: number; //1 默认 2 限制最多可选个数
+  type?: number; // 1 默认 2 限制最多可选个数
 }
 
-const NavSelecter = (props: NavSelecter) => {
-  const { onVisibleChange, data, value = [], onChecked, title, type = 1 } = props;
-  const [checkedIds, set_checkedIds] = useState<(string | number)[]>([]);
-  const [checkedItems, set_checkedItems] = useState<NavSelecterItemType[]>([]);
+const NavSelecter: React.FC<NavSelecterProps> = ({
+  onVisibleChange,
+  data,
+  value = [],
+  onChecked,
+  title,
+  type = 1,
+}) => {
+  const [checkedIds, setCheckedIds] = useState<(string | number)[]>(value);
 
   const onChange = (tab: NavSelecterItemType) => {
-    let _checkedIds = [...checkedIds];
-    let _checkedItems = [...checkedItems];
-
-    if (_checkedIds.includes(tab.menuId)) {
-      _checkedIds.splice(checkedIds.indexOf(tab.menuId), 1);
-      _checkedItems.splice(
-        _checkedItems.findIndex((t) => t.menuId == tab.menuId),
-        1,
-      );
-      set_checkedIds([..._checkedIds]);
-      set_checkedItems([..._checkedItems]);
+    let updatedCheckedIds = [...checkedIds];
+    
+    if (updatedCheckedIds.includes(tab.menuId)) {
+      updatedCheckedIds = updatedCheckedIds.filter(id => id !== tab.menuId);
     } else {
-      if (type == 2 && checkedIds.length + 1 > 6) {
+      if (type === 2 && updatedCheckedIds.length >= 6) {
         message.warn('快速入口最多展示6项');
         return;
       }
-
-      _checkedIds.push(tab.menuId);
-      _checkedItems.push(tab);
-      set_checkedItems([..._checkedItems]);
-      set_checkedIds([..._checkedIds]);
+      updatedCheckedIds.push(tab.menuId);
     }
+
+    setCheckedIds(updatedCheckedIds);
   };
 
-  const onMaskClick = (e: React.MouseEvent) => {
+  const onMaskClick = () => {
     onVisibleChange && onVisibleChange(false);
   };
 
   const onCommit = () => {
-    onChecked && onChecked(checkedItems);
+    if (data) {
+      const selectedItems: NavSelecterItemType[] = [];
+      data.forEach(tree => {
+        const nodes = findNodesBySomes(tree, new Set(checkedIds), 'menuId');
+        if (nodes) {
+          nodes.forEach(node => {
+            selectedItems.push({
+              name: node.name,
+              menuId: node.menuId,
+              path: node.path,
+              type: node.type,
+              contentType: node.contentType,
+              systemId: node.systemId || `${node.menuId}`,
+            });
+          });
+        }
+      });
+      onChecked && onChecked(selectedItems);
+    }
     onVisibleChange && onVisibleChange(false);
   };
 
   const onReset = () => {
-    set_checkedItems([]);
-    set_checkedIds([]);
+    setCheckedIds([]);
   };
 
-  const checkAllHandle = (e: any) => {
-    let all: any[] = [];
-
-    if (e.target.checked) {
-      data?.forEach((item) => {
-        const _result = getLeafNodes({ child: item.child });
-        all = [...all, ..._result];
+  const checkAllHandle = (e:CheckboxChangeEvent) => {
+    if (e.target.checked && data) {
+      const allIds: (string | number)[] = [];
+      data.forEach(item => {
+        const leafNodes = getLeafNodes({ child: item.child });
+        leafNodes.forEach(leaf => allIds.push(leaf.menuId));
       });
-      set_checkedItems([...all]);
-      set_checkedIds(all.map((a) => a.menuId));
+      if (type === 2 && allIds.length > 6) {
+        message.warn('快速入口最多展示6项');
+        return;
+      }
+      setCheckedIds(allIds);
     } else {
-      set_checkedItems([]);
-      set_checkedIds([]);
+      setCheckedIds([]);
     }
   };
 
   useEffect(() => {
-    if (data) {
-      let result: any[] = [];
+    setCheckedIds(value);
+  }, [value]);
 
-      for (let tree of data) {
-        const node = findNodesBySomes(tree, new Set(checkedIds), 'menuId');
-        if (node) {
-          result = result.concat([...node]);
+  const getCheckedItems = (): NavSelecterItemType[] => {
+    const selectedItems: NavSelecterItemType[] = [];
+    if (data) {
+      data.forEach(tree => {
+        const nodes = findNodesBySomes(tree, new Set(checkedIds), 'menuId');
+        if (nodes) {
+          nodes.forEach(node => {
+            selectedItems.push({
+              name: node.name,
+              menuId: node.menuId,
+              path: node.path,
+              type: node.type,
+              contentType: node.contentType,
+              systemId: node.systemId || `${node.menuId}`,
+            });
+          });
         }
-      }
-      set_checkedItems(result);
+      });
     }
-  }, [checkedIds]);
+    return selectedItems;
+  };
 
-  useEffect(() => {
-    set_checkedIds(value);
-  }, [value]);
+  const checkedItems = getCheckedItems();
 
   return (
-    <div className="navSelecter" onClick={(e) => onMaskClick(e)}>
+    <div className="navSelecter" onClick={onMaskClick}>
       <div className="container">
         <div className="selecterTitle">{title}</div>
-        <div className="closeBtn" onClick={(e) => onMaskClick(e)}>
-          <img src={require('./images/close.png')} />
+        <div className="closeBtn" onClick={onMaskClick}>
+          <img src={require('./images/close.png')} alt="Close" />
         </div>
-        <div className="content" onClick={(e) => e.stopPropagation()}>
-          <div>
-            <Tabs defaultActiveKey="1">
-              {data?.map((val) => (
-                <TabPane tab={`${val.name}(${getLeafNodes({ child: val.child }).length})`} key={val.menuId}>
-                  <div className="contentInner">
-                    {val.child?.map((item) => (
-                      <div className="row" key={item.menuId}>
-                        <div className="rowName">{item.name}</div>
-                        <div className="rowWrap">
-                          {item.child?.map((a) => {
-                            if (a.type == 3 || a.type == 1) {
-                              return (
-                                <div className="tab" key={a.menuId}>
-                                  <Checkbox
-                                    onChange={() =>
-                                      onChange({
-                                        name: a.name,
-                                        menuId: a.menuId,
-                                        path: a.path,
-                                        type: a.type,
-                                        contentType: a.contentType,
-                                        systemId: a.systemId,
-                                      })
-                                    }
-                                    checked={checkedIds.includes(a.menuId)}
-                                  ></Checkbox>
-                                  <span style={{ display: 'inline-block', width: '75%', marginLeft: 8, whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{a.name}</span>
-                                </div>
-                              );
-                            }
-                          })}
-                        </div>
+        <div className="content" onClick={e => e.stopPropagation()}>
+          <Tabs defaultActiveKey="1">
+            {data?.map(val => (
+              <TabPane
+                tab={`${val.name}(${getLeafNodes({ child: val.child }).length})`}
+                key={val.menuId}
+              >
+                <div className="contentInner">
+                  {val.child?.map(item => (
+                    <div className="row" key={item.menuId}>
+                      <div className="rowName">{item.name}</div>
+                      <div className="rowWrap">
+                        {item.child?.map(a => {
+                          if (a.type === 3 || a.type === 1) {
+                            return (
+                              <div className="tab" key={a.menuId}>
+                                <Checkbox
+                                  onChange={() =>
+                                    onChange({
+                                      name: a.name,
+                                      menuId: a.menuId,
+                                      path: a.path,
+                                      type: a.type,
+                                      contentType: a.contentType,
+                                      systemId: a.systemId,
+                                    })
+                                  }
+                                  checked={checkedIds.includes(a.menuId)}
+                                />
+                                <span
+                                  style={{
+                                    display: 'inline-block',
+                                    width: '75%',
+                                    marginLeft: 8,
+                                    whiteSpace: 'nowrap',
+                                    textOverflow: 'ellipsis',
+                                    overflow: 'hidden',
+                                  }}
+                                >
+                                  {a.name}
+                                </span>
+                              </div>
+                            );
+                          }
+                          return null;
+                        })}
                       </div>
-                    ))}
-                  </div>
-                </TabPane>
-              ))}
-            </Tabs>
-          </div>
+                    </div>
+                  ))}
+                </div>
+              </TabPane>
+            ))}
+          </Tabs>
         </div>
-        <div className="footer" onClick={(e) => e.stopPropagation()}>
+        <div className="footer" onClick={e => e.stopPropagation()}>
           <span className="count">
-            {type == 1 && <Checkbox onChange={(e) => checkAllHandle(e)}>全部开启 </Checkbox>}
-            {type == 1 && <span className="count">{`已选中${checkedIds.length}项`}</span>}
-            {type == 2 && `当前快速入口已展示${checkedItems.length}/6项`}
+            {type === 1 && (
+              <Checkbox onChange={checkAllHandle}>
+                全部开启
+              </Checkbox>
+            )}
+            {type === 1 && (
+              <span className="count">{`已选中${checkedIds.length}项`}</span>
+            )}
+            {type === 2 && `当前快速入口已展示${checkedItems.length}/6项`}
           </span>
           <div className="btnGroup">
-            <Button className="resetBtn btn" style={{ marginRight: 8 }} onClick={onReset}>
+            <Button
+              className="resetBtn btn"
+              style={{ marginRight: 8 }}
+              onClick={onReset}
+            >
               重置
             </Button>
-            <Button className="confirmBtn btn" type="primary" onClick={onCommit}>
+            <Button
+              className="confirmBtn btn"
+              type="primary"
+              onClick={onCommit}
+            >
               确定
             </Button>
           </div>

binární
src/components/topBar/images/groupIcon.png


+ 77 - 61
src/components/topBar/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-11-16 09:12:37
- * @LastEditTime: 2024-12-03 14:54:16
+ * @LastEditTime: 2024-12-31 13:48:33
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/index/components/topBar/index.tsx
@@ -11,7 +11,7 @@ import React, { useEffect, useState } from 'react';
 
 import './style.less';
 
-import { Input, Modal, Tooltip } from 'antd';
+import { Input, Modal, Popover, Tooltip } from 'antd';
 import { LogoutOutlined, SettingOutlined } from '@ant-design/icons';
 
 // import logo from '../../../public/images/kc-logo.png';
@@ -32,18 +32,18 @@ interface TopBarType {
   onTabClick?: (data: TopBar.Tab) => void;
   userData?: { name: string;[key: string]: any };
   navData: TopBar.PanelData[];
-  logo?:string;
-  topBarTitle?:string;
+  logo?: string;
+  topBarTitle?: string;
 }
 
 
 const TopBar: React.FC<TopBarType> = (props) => {
-  const { onTabChange, userPannelTabClick, onCloseTab, onTabClick, userData, navData, currentTab,logo=undefined,topBarTitle='欢迎进入医管平台' } = props;
+  const { onTabChange, userPannelTabClick, onCloseTab, onTabClick, userData, navData, currentTab, logo = undefined, topBarTitle = '欢迎进入医管平台' } = props;
   const [systemTabs, setSystemTabs] = useState<TopBar.Tab[]>([]); //已打开的tab
   const [currentSelectedTab, setCurrentSelectedTab] = useState<TopBar.Tab>();
   const [ifOpenPannel, setIfOpenPannel] = useState(false);
   const [arrowRotate, setArrowRotate] = useState(false);
-  const [pageTitle, set_pageTitle] = useState('');
+  // const [pageTitle, set_pageTitle] = useState('');
   const [currentActivedBlockIndex, set_currentActivedBlockIndex] = useState(0);
   const [panelData, set_panelData] = useState<TopBar.PanelData[]>([]);
 
@@ -51,11 +51,13 @@ const TopBar: React.FC<TopBarType> = (props) => {
   const [onTabSystemTabs_hide, set_onTabSystemTabs_hide] = useState<TopBar.Tab[]>([]);  //下拉掩藏的导航
 
   const { initialState, setInitialState } = useModel('@@initialState');
-  const [tokenUpdateModalVisible,set_tokenUpdateModalVisible] = useState(false);
+  const [tokenUpdateModalVisible, set_tokenUpdateModalVisible] = useState(false);
   const location = useLocation();
 
   const [showMoreTabPannel, set_showMoreTabPannel] = useState(false);
-  const [password,set_password] = useState<string|undefined>(undefined);
+  const [password, set_password] = useState<string | undefined>(undefined);
+  const [showGroupList, set_showGroupList] = useState(false);
+  const [groupList,set_groupList] = useState<any[]>([]);
 
 
   const localSavedTab = localStorage.getItem('currentSelectedTab');
@@ -69,7 +71,7 @@ const TopBar: React.FC<TopBarType> = (props) => {
     //导航栏tab点击
     // console.log('_systemTabClickHandle',item);
     onTabClick && onTabClick(item);
-    if(item.type != 1&&item.contentType != 7){
+    if (item.type != 1 && item.contentType != 7) {
       localStorage.setItem('currentSelectedTab', JSON.stringify(item));
       setCurrentSelectedTab(item);
     }
@@ -79,9 +81,9 @@ const TopBar: React.FC<TopBarType> = (props) => {
 
   const _systemListClickHandle = (data: TopBar.Tab, currentActivedBlockIndex: number, index: number, i: number) => {
     //导航栏系统菜单列表点击回调
- 
+
     if (currentSelectedTab?.menuId == data.menuId) return;
-    
+
     //临时保存衣打开过的菜单
     const t = localStorage.getItem('visitedTabs');
 
@@ -98,7 +100,8 @@ const TopBar: React.FC<TopBarType> = (props) => {
 
     _systemTabClickHandle(data); //触发一次tab点击
 
-    set_pageTitle(panelData[currentActivedBlockIndex].child[index].name)
+    // set_pageTitle(panelData[currentActivedBlockIndex].child[index].name);
+    setInitialState((s: any) => ({ ...s, pageTitle: panelData[currentActivedBlockIndex].child[index].name }))
 
     if (panelData[currentActivedBlockIndex].child[index].child) {
       //console.log([...panelData[currentActivedBlockIndex].child[index].child])
@@ -129,7 +132,7 @@ const TopBar: React.FC<TopBarType> = (props) => {
     if (delIndex != 0) {
       _systemTabClickHandle(_systemTabs[delIndex - 1]); //自动切换为前一个tab
     }
-    
+
     onTabChange && onTabChange(filtered);
     onCloseTab && onCloseTab(item);
   };
@@ -161,7 +164,7 @@ const TopBar: React.FC<TopBarType> = (props) => {
       setSystemTabs([]); //清空tab导航
       onTabChange && onTabChange([]);
       setCurrentSelectedTab(undefined);
-      set_pageTitle(topBarTitle);
+      setInitialState((s: any) => ({ ...s, pageTitle: topBarTitle }))
       setIfOpenPannel(false);
       console.log('goHome');
       localStorage.removeItem('currentSelectedTab');
@@ -204,10 +207,10 @@ const TopBar: React.FC<TopBarType> = (props) => {
     _systemTabClickHandle(systemData);
     const temp = onTabSystemTabs[onTabSystemTabs.length - 1];
     const _onTabSystemTabs = [...onTabSystemTabs];
-    const b = _onTabSystemTabs.filter(a => (a.systemId?a.systemId:a.menuId) != (temp.systemId?temp.systemId:temp.menuId));
-  
+    const b = _onTabSystemTabs.filter(a => (a.systemId ? a.systemId : a.menuId) != (temp.systemId ? temp.systemId : temp.menuId));
+
     set_onTabSystemTabs([...b, systemData]);
-    set_onTabSystemTabs_hide([...onTabSystemTabs_hide.filter(a => (a.systemId?a.systemId:a.menuId) != (systemData.systemId?systemData.systemId:systemData.menuId)), temp])
+    set_onTabSystemTabs_hide([...onTabSystemTabs_hide.filter(a => (a.systemId ? a.systemId : a.menuId) != (systemData.systemId ? systemData.systemId : systemData.menuId)), temp])
   }
 
 
@@ -235,7 +238,8 @@ const TopBar: React.FC<TopBarType> = (props) => {
                 for (let k = 0; k < _systems.length; k++) {
                   if (_systems[k].menuId == _currentSelectedTabFromLocal.menuId) {
                     set_currentActivedBlockIndex(blockIndex);
-                    set_pageTitle(_panelData[blockIndex].child[channelIndex].name); //设置体系标题
+                    // set_pageTitle(_panelData[blockIndex].child[channelIndex].name); //设置体系标题
+                    setInitialState((s: any) => ({ ...s, pageTitle: _panelData[blockIndex].child[channelIndex].name }))
 
                     break one;
                   }
@@ -254,8 +258,8 @@ const TopBar: React.FC<TopBarType> = (props) => {
       }
 
       // console.log({_currentSelectedTabFromLocal,location});
-      const {pathname} = location;
-      if(pathname.indexOf(_currentSelectedTabFromLocal.path) == -1){
+      const { pathname } = location;
+      if (pathname.indexOf(_currentSelectedTabFromLocal.path) == -1) {
         history.push(_currentSelectedTabFromLocal.path);
       }
 
@@ -287,19 +291,19 @@ const TopBar: React.FC<TopBarType> = (props) => {
   };
 
   const updateToken = async () => {
-        const account = (localStorage.getItem('account')) as string;
-        const hospSign = localStorage.getItem('hospSign');
-        const data = {
-          account,
-          password:password,
-          hospSign
-        }
-        const resp = await updateTokenReq(data);
-        if(resp){
-          set_password(undefined);
-          set_tokenUpdateModalVisible(false);
-          window.location.reload();
-        }
+    const account = (localStorage.getItem('account')) as string;
+    const hospSign = localStorage.getItem('hospSign');
+    const data = {
+      account,
+      password: password,
+      hospSign
+    }
+    const resp = await updateTokenReq(data);
+    if (resp) {
+      set_password(undefined);
+      set_tokenUpdateModalVisible(false);
+      window.location.reload();
+    }
   }
 
 
@@ -319,9 +323,9 @@ const TopBar: React.FC<TopBarType> = (props) => {
   }, [currentTab]);
 
 
-  useEffect(()=>{
-     set_pageTitle(topBarTitle);
-  },[topBarTitle])
+  useEffect(() => {
+    setInitialState((s: any) => ({ ...s, pageTitle: topBarTitle }))
+  }, [topBarTitle])
 
 
 
@@ -356,22 +360,23 @@ const TopBar: React.FC<TopBarType> = (props) => {
 
   useEffect(() => {
 
-    //_systemTabClickHandle(currentSelectedTabFromLocal);  //恢复选中的tab
+    // _systemTabClickHandle(currentSelectedTabFromLocal);  //恢复选中的tab
 
     document.body.addEventListener('click', (e: any) => {
 
-      const classes = ['panel', 'typeBlockName', 'left', 'typeBlockIcon', 'typeBlock', 'typeBlock active', 'active', 'right', 'row', 'rowDetai', 'channelName', 'channelList', 'systemTab', 'channelIcon', 'rowDetail','typeBlockIcon typeBlockIcon1','typeBlockIcon typeBlockIcon2','typeBlockIcon typeBlockIcon3','typeBlockIcon typeBlockIcon4','typeBlockIcon typeBlockIcon5','typeBlockIcon typeBlockIcon6','typeBlockIcon typeBlockIcon7','typeBlockIcon typeBlockIcon8','typeBlockIcon typeBlockIcon9'];
+      const classes = ['panel', 'typeBlockName', 'left', 'typeBlockIcon', 'typeBlock', 'typeBlock active', 'active', 'right', 'row', 'rowDetai', 'channelName', 'channelList', 'systemTab', 'channelIcon', 'rowDetail', 'typeBlockIcon typeBlockIcon1', 'typeBlockIcon typeBlockIcon2', 'typeBlockIcon typeBlockIcon3', 'typeBlockIcon typeBlockIcon4', 'typeBlockIcon typeBlockIcon5', 'typeBlockIcon typeBlockIcon6', 'typeBlockIcon typeBlockIcon7', 'typeBlockIcon typeBlockIcon8', 'typeBlockIcon typeBlockIcon9'];
       if (e.target) {
-        let key = e.target.className?e.target.className:'';
-        if (classes.includes(key)||(typeof key == 'string'&&key.indexOf('typeBlockIcon') != -1)) {
+        let key = e.target.className ? e.target.className : '';
+        if (classes.includes(key) || (typeof key == 'string' && key.indexOf('typeBlockIcon') != -1)) {
           return
         }
       }
       setIfOpenPannel(false);
+      set_showGroupList(false);
     });
-    
+
     // 事件监听器的函数定义
-    const handleStorageChange = (e:any) => {
+    const handleStorageChange = (e: any) => {
       if (e.key === 'tokenExpired') {
         set_tokenUpdateModalVisible(true);
       }
@@ -389,31 +394,31 @@ const TopBar: React.FC<TopBarType> = (props) => {
 
   return (
     <div className='topBar' onClick={e => e.stopPropagation()}>
-      <Modal className='TokenUpdateModal' open={tokenUpdateModalVisible} width={400} title={false}  footer={false} closable={false}  >
-           <div className='content'>                                                                                                                                                                         
-                <div className='title'>登录超时锁定</div>
-                <div className='form'>
-                      <div className='avatar'>
-                         <img className='avatarImg' src={require('../../../public/images/initAvatar.png')} alt="" />
-                         <img className='suoding' src={require('../../../public/images/suoding.png')} alt="" />
-                      </div>
-                      <div className='name'>{userData?.name}</div>
-                      <Input onChange={(e)=>set_password(e.target.value)} value={password}  
-                      className='input' autoComplete='off' onKeyDown={(e)=>e.key === 'Enter'&&updateToken()} />
-                      <div className='updateBtn' onClick={()=>updateToken()}>解锁</div>
-                      <a onClick={()=>logoutHandle()}>退出登录</a>
-                </div>
-           </div>
+      <Modal className='TokenUpdateModal' open={tokenUpdateModalVisible} width={400} title={false} footer={false} closable={false}  >
+        <div className='content'>
+          <div className='title'>登录超时锁定</div>
+          <div className='form'>
+            <div className='avatar'>
+              <img className='avatarImg' src={require('../../../public/images/initAvatar.png')} alt="" />
+              <img className='suoding' src={require('../../../public/images/suoding.png')} alt="" />
+            </div>
+            <div className='name'>{userData?.name}</div>
+            <Input onChange={(e) => set_password(e.target.value)} value={password}
+              className='input' autoComplete='off' onKeyDown={(e) => e.key === 'Enter' && updateToken()} />
+            <div className='updateBtn' onClick={() => updateToken()}>解锁</div>
+            <a onClick={() => logoutHandle()}>退出登录</a>
+          </div>
+        </div>
       </Modal>
       <div className='logoWrap'>
-        {logo&&<img className='logo' src={logo} onClick={() => goToHome()} />}
+        {logo && <img className='logo' src={logo} onClick={() => goToHome()} />}
         <Divider type="vertical" style={{ background: 'white', height: 16, opacity: 0.29, position: 'relative', top: 1, marginLeft: 16, marginRight: 8 }} />
         <div className={ifOpenPannel ? 'menu active' : 'menu'} onClick={() => openNav()}>
           <img src={require('../../../public/images/menu.png')} alt="" />
         </div>
         <span className='systemTitle'
         //  onClick={() => goSystemIndex(pageTitle)}
-         >{pageTitle}</span>
+        >{initialState?.pageTitle}</span>
       </div>
 
       <div className='userRelaInfoWrap'>
@@ -453,9 +458,20 @@ const TopBar: React.FC<TopBarType> = (props) => {
         <div className='notification'>
           <img className='notificationIcon' src={require('../../../public/images/notificationIcon.png')} />
         </div>
+        <div className='group'>
+          <Tooltip title="运营管理部" placement='right'><div className='group-switcher' onClick={()=>set_showGroupList(!showGroupList)}><img src={require('./images/groupIcon.png')} alt="" /></div></Tooltip>
+          {
+            showGroupList && (
+              <div className='group-list-wrapper'>
+                <div className='group-list active'>后勤管理部</div>
+                <div className='group-list'>后勤管理部</div>
+              </div>
+            )
+          }
+        </div>
         <Tooltip className='topBarTooltip' placement='bottomRight' title={<UserPannel />} color="#fff" onOpenChange={(visible) => setArrowRotate(visible)}>
           <div className='user'>
-            <div className='avator'><img src={userData?.avatarUrl?userData.avatarUrl:require('../../../public/images/avatar.png')} /></div>
+            <div className='avator'><img src={userData?.avatarUrl ? userData.avatarUrl : require('../../../public/images/avatar.png')} /></div>
             <div className='info'>
               <span className='hospName'>{localStorage.getItem('hospAbbreviation')}</span>
               <span className='name'>{userData?.name}</span>
@@ -487,7 +503,7 @@ const TopBar: React.FC<TopBarType> = (props) => {
                 panelData.length > 0 && panelData[currentActivedBlockIndex] && panelData[currentActivedBlockIndex].child && panelData[currentActivedBlockIndex].child.map((item, index: number) => {
                   return (
                     <div className='row' key={index}>
-                      <img className='channelIcon' src={item.icon?item.icon:require(`../../../public/images/tongyong_tixi.png`)} alt="" />
+                      <img className='channelIcon' src={item.icon ? item.icon : require(`../../../public/images/tongyong_tixi.png`)} alt="" />
                       <div className='rowDetail'>
                         <div className='channelName' onClick={() => goChannelIndex(item)}>{item.name}</div>
                         <div className='channelList'>

+ 61 - 8
src/components/topBar/style.less

@@ -8,6 +8,7 @@
 .TokenUpdateModal {
   .kcmp-ant-modal-content {
     background: linear-gradient(180deg, #e8f1fc 0%, #ffffff 100%) !important;
+
     .kcmp-ant-modal-body {
       background-image: url('../../../public/images/tokenUpdateModalbg.png') !important;
       background-size: 320px 180px !important;
@@ -35,10 +36,12 @@
             width: 64px;
             height: 64px;
             margin-bottom: 8px;
+
             .avatarImg {
               width: 100%;
               height: 100%;
             }
+
             .suoding {
               position: absolute;
               bottom: 0;
@@ -102,7 +105,7 @@
     padding-left: 12px;
     border-radius: 2px;
 
-    & > span {
+    &>span {
       &:last-child {
         margin-left: 8px;
       }
@@ -183,7 +186,7 @@
       transition: all 0.3s ease-in;
       background: rgba(254, 255, 255, 0);
 
-      & > img {
+      &>img {
         width: 16px;
         height: 16px;
       }
@@ -197,7 +200,7 @@
       }
     }
 
-    & > span {
+    &>span {
       font-size: 14px;
       font-family: SourceHanSansCN-Medium, SourceHanSansCN;
       font-weight: 500;
@@ -363,6 +366,55 @@
       }
     }
 
+    .group {
+      position: relative;
+
+      .group-switcher {
+        display: flex;
+        cursor: pointer;
+        justify-content: center;
+        align-items: center;
+        width: 32px;
+        height: 32px;
+        border-radius: 4px;
+        margin-right: 8px;
+
+        &>img {
+          width: 24px;
+          height: 24px;
+        }
+
+        &:hover {
+          background: rgba(249, 248, 248, 0.1);
+        }
+      }
+
+      .group-list-wrapper {
+        position: absolute;
+        padding: 4px;
+        top:40px;
+        background: #ffffff;
+        border-radius: 4px;
+        .group-list {
+          width: 152px;
+          height: 32px;
+          text-align: left;
+          border-radius: 2px;
+          font-weight: 400;
+          font-size: 14px;
+          color: #17181A;
+          line-height: 32px;
+          padding-left: 8px;
+          cursor: pointer;
+          &.active {
+            font-weight: bold;
+            color: #17181A;
+            background: rgba(51, 119, 255, 0.08);
+          }
+        }
+      }
+    }
+
     .user {
       cursor: pointer;
       display: flex;
@@ -389,8 +441,8 @@
         border: 1px solid #ffffff;
 
         img {
-          width: 101%;
-          height: 101%;
+          width: 32px;
+          height: 32px;
         }
       }
 
@@ -473,7 +525,7 @@
           margin-bottom: 8px;
         }
 
-        & > span {
+        &>span {
           font-size: 12px;
           font-family: SourceHanSansCN-Normal, SourceHanSansCN;
           font-weight: 400;
@@ -533,12 +585,13 @@
             background-size: contain;
           }
 
-          & > span {
+          &>span {
             color: #3376fe;
           }
         }
 
         &:hover {
+
           // background: #F5F7FA;
           .typeBlockIcon1 {
             background: url('../../../public/images/jingyiyiliao.png');
@@ -565,7 +618,7 @@
             background-size: contain;
           }
 
-          & > span {
+          &>span {
             color: #3376fe;
           }
         }

+ 6 - 4
src/layouts/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-11-09 13:56:33
- * @LastEditTime: 2024-11-19 16:39:20
+ * @LastEditTime: 2024-12-26 11:12:10
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/layouts/index.tsx
@@ -150,10 +150,10 @@ export default function Layout({ children, location, route, history, match }: IR
     if (resp) {
       resp.forEach((item: any) => {
         if (item.code == '1739122834787143680') {
-          set_topBarLogoUrl(item.value);
+          item.value&&set_topBarLogoUrl(item.value);
         }
         if (item.code == '1739123252502073344') {
-          set_topBarTitle(item.value);
+          item.value&&set_topBarTitle(item.value);
         }
       });
     }
@@ -187,6 +187,8 @@ export default function Layout({ children, location, route, history, match }: IR
     }
   });
 
+
+
   if (location.pathname == '/login') {
     return <div>{children}</div>;
   }
@@ -254,7 +256,7 @@ export default function Layout({ children, location, route, history, match }: IR
           <h1>{emptyPageContent}</h1>
         </div>
       )}
-      {!isEmpty && <div style={{ height:noTopBar == 'true'?'auto': `calc(100vh - 48px)`, overflowY: 'scroll', minWidth: 1280 }}>{children}</div>}
+      {!isEmpty && <div style={{ height:noTopBar == 'true'?'auto': `calc(100vh - 48px)`, minWidth: 1280 }}>{children}</div>}
     </ProLayout>
   );
 }

+ 1 - 2
src/pages/document.ejs

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2022-02-14 14:02:45
- * @LastEditTime: 2024-04-29 11:08:58
+ * @LastEditTime: 2024-12-10 16:47:13
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/document.ejs
@@ -17,7 +17,6 @@
   name="viewport"
   content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
 />
-  <title>精益管理中台</title>
   <link rel="icon" href="/favicon.ico" type="image/x-icon" id="favicon">
   <!-- <link rel="icon" href="<%= context.favicon %>" type="image/x-icon"> -->
   <!-- <link rel="icon" href="<%= context.config.publicPath +'favicon.ico'%>" type="image/x-icon" /> -->

+ 18 - 91
src/pages/index/components/FastEntry/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2022-05-27 14:17:59
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2024-10-12 15:08:21
+ * @LastEditTime: 2024-12-26 11:09:38
  * @FilePath: /KC-MiddlePlatform/src/pages/index/components/FastEntry/index.tsx
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -24,9 +24,11 @@ export type FastEntryTabType = {
   type: number;
   contentType: number;
   menuId: number | string;
+  url?:string
 };
 export interface FastEntryType {
   data: FastEntryTabType[];
+  onChange?:()=>void;
 }
 
 const IconFont = createFromIconfontCN({
@@ -35,7 +37,6 @@ const IconFont = createFromIconfontCN({
 
 export const FastEntry = (props: FastEntryType) => {
   const { initialState, setInitialState } = useModel('@@initialState');
-
   const [tabs, set_tabs] = useState<FastEntryTabType[]>([]);
   const [open, set_open] = useState(false);
   const [navSelecterData, set_navSelecterData] = useState<NavSelecterData[]>([]);
@@ -44,18 +45,17 @@ export const FastEntry = (props: FastEntryType) => {
     const { systemId = '', menuId = '', contentType, type,url } = tab;
     const resp = await getAppAccess(systemId.length > 0 ? systemId : menuId);
     if (!resp) {
-      if(contentType != 7 && type == 1){
-        await setInitialState((s) => ({ ...s, currentSelectedSys: tab as any, currentTab: tab }));
-      }
-     
-      if (type == 1 && contentType == 6) {
-        //体系或第三方iframe
-        history.push('/platform');
-      }else if(type == 1 && contentType == 7){
-        window.open(url,'_blank');
-      }else {
-        history.push(tab.path);
+      if(contentType != 7&&type != 1){
+         setInitialState((s:any) => ({ ...s, currentSelectedSys: tab as any, currentTab: tab }));
       }
+      // if (type == 1 && contentType == 6) {
+      //   //体系或第三方iframe
+      //   history.push('/platform');
+      // }else if(type == 1 && contentType == 7){
+      //   window.open(url,'_blank');
+      // }else {
+      //   history.push(tab.path);
+      // }
     } else {
       Modal.error({
         title: '当前系统未注册,请联系管理员处理!',
@@ -72,96 +72,23 @@ export const FastEntry = (props: FastEntryType) => {
     const resp = await addFastEntry(data as AddFastEntryDataType[]);
     if (resp) {
       set_tabs(data);
+      const {onChange} = props;
+      onChange&&onChange();
     }
   };
 
-  const addHandle = () => {
+  const addHandle = () => {                                                                                                                                                                                                                                                                                                                      
     getNavData();
     set_open(true);
   };
-
+  
   useEffect(() => {
     const { data } = props;
     set_tabs(data);
   }, [props]);
 
   useEffect(() => {
-    // set_navSelecterData([
-    //       {
-    //         name:'精益医疗管理',
-    //         key:0,
-    //         children:[
-    //             {
-    //                 name:'质量安全管理',
-    //                 key:1,
-    //                 children:[
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:2
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:3
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:4
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:20
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:21
-    //                     }
-    //                 ]
-    //             },
-    //             {
-    //                 name:'质量安全管理2',
-    //                 key:30,
-    //                 children:[
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:31
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:32
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:33
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:34
-    //                     },
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:35
-    //                     }
-    //                 ]
-    //             }
-    //         ]
-    //       },
-    //       {
-    //         name:'HBI',
-    //         key:5,
-    //         children:[
-    //             {
-    //                 name:'质量安全管理',
-    //                 key:6,
-    //                 children:[
-    //                     {
-    //                         name:'质量管理及十大安全目标',
-    //                         key:7
-    //                     }
-    //                 ]
-    //             }
-    //         ]
-    //       }
-    // ])
+   
   }, []);
 
   return (

+ 12 - 5
src/pages/index/index.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2021-11-10 09:33:30
- * @LastEditTime: 2024-07-25 15:03:07
+ * @LastEditTime: 2024-12-27 15:04:08
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/index.tsx
@@ -35,11 +35,13 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
     systemLists, //当前医院可选子系统列表
     setInitialState,
     userData,
+    customerType
   } = useModel('@@initialState', (model) => {
     return {
       systemLists: model.initialState?.systemLists,
       setInitialState: model.setInitialState,
       userData: model.initialState?.userData,
+      customerType:model.initialState?.customerType,
     };
   });
 
@@ -144,6 +146,10 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
     set_drawerOpen(false);
   };
 
+  const fastEntryOnChangeHandle = ()=>{
+    getIndexPageDataFunc();
+  }
+
   useEffect(() => {
     if (allParams) {
       setIframeUrl(allParams);
@@ -235,13 +241,14 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
                 <div className="row">
                   <div className="label">
                     <img src={require('../../../public/images/icon-keshi.png')} alt="" />
-                    <span>科室</span>
+                    <span>{customerType == '2'?'组织':'科室'}</span>
                     {userInfo?.departmentName ? userInfo?.departmentName : '-'}
                   </div>
                   <div className="label">
                     <img src={require('../../../public/images/icon-zhicheng.png')} alt="" />
-                    <span>职称</span>
-                    {userInfo?.title ? userInfo?.title : '-'}
+                    <span>{customerType == '2'?'职务':'职称'}</span>
+                    {customerType == '2'&&<>{userInfo?.jobTitle??'-'}</>}
+                    {customerType == '1'&&<>{userInfo?.title??'-'}</>}
                   </div>
                 </div>
                 <div className="row">
@@ -260,7 +267,7 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
             </div>
           </div>
           <div className="cardTwo">
-            <FastEntry data={fastEntry} />
+            <FastEntry data={fastEntry} onChange={()=>fastEntryOnChangeHandle()} />
           </div>
           <div className="cardThree">
             <TodoList todoList={todoList} todoListClickHandle={todoListClickHandle} />

+ 40 - 0
src/pages/login/ErrorBoundary.tsx

@@ -0,0 +1,40 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2024-12-11 11:07:41
+ * @LastEditors: code4eat awesomedema@gmail.com
+ * @LastEditTime: 2024-12-11 11:08:26
+ * @FilePath: /KC-MiddlePlatform/src/pages/login/ErrorBoundary.tsx
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+import React from 'react';
+
+interface ErrorBoundaryState {
+  hasError: boolean;
+  error: Error | null;
+  errorInfo: React.ErrorInfo | null;
+}
+
+export class ErrorBoundary extends React.Component<{}, ErrorBoundaryState> {
+  constructor(props: {}) {
+    super(props);
+    this.state = { hasError: false, error: null, errorInfo: null };
+  }
+
+  static getDerivedStateFromError(error: Error) {
+    // 当子组件抛出错误时更新 state,用于 fallback UI 的显示
+    return { hasError: true, error: error };
+  }
+
+  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
+    // 这里可以将错误信息上报到日志分析服务
+    console.error('ErrorBoundary caught an error:', error, errorInfo);
+  }
+
+  render() {
+    if (this.state.hasError) {
+      // 这里展示一个简短的 fallback UI
+      return <div>很抱歉,页面加载出现错误。</div>;
+    }
+    return this.props.children;
+  }
+}

+ 67 - 43
src/pages/login/index.tsx

@@ -1,31 +1,32 @@
 /*
  * @Author: your name
  * @Date: 2021-11-09 14:58:08
- * @LastEditTime: 2024-11-15 14:38:05
+ * @LastEditTime: 2024-12-13 14:03:41
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/login/index.tsx
  */
 
 import React, { useRef, useEffect, useState } from 'react';
-import { Select, notification, Row, Col, Modal } from 'antd';
+import { Select, notification, Row, Col } from 'antd';
 import './style.less';
 
 import { useModel, history, Location, Helmet } from 'umi';
 
 import { Form, Input, Button } from 'antd';
 
-import logo from '../../../public/images/kclogo_colorful.png';
-
 import KCSelect from '@/components/kc-select';
 
 import { getHospConfigBySign, getLastLoginSys, login } from '@/service/login';
 
 import { KcimCenterSysId } from '@/constant';
+import { getSysParamsByCode } from '@/service';
+import { ErrorBoundary } from './ErrorBoundary';
+
 
 const { Option } = Select;
 
-function changeFavicon(src: string) {
+export function changeFavicon(src: string) {
   const link = document.createElement('link');
   const oldLink = document.getElementById('favicon');
   link.id = 'favicon';
@@ -69,7 +70,16 @@ export const handleLogin = async (
   return null;
 };
 
-const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
+export const getHospType = async () => {
+  const resp = await getSysParamsByCode(KcimCenterSysId, '1864939559301812224');
+  if (resp && resp.length > 0) {
+    return resp[0].value;
+  } else {
+    return undefined;
+  }
+};
+
+const LoginPage: React.FC<Partial<LoginPageType>> = ({ location = { pathname: '/login' } as Location, children, title = '欢迎进入医务管理系统' }) => {
   const loginPageRef = useRef<HTMLDivElement>(null);
   const [subHospList, setSubHospList] = useState<
     {
@@ -78,10 +88,13 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
       hospAbbreviation: any;
       name: string;
       value: string | number;
+      loginPic?: string;
+      loginTips?: string;
+      systemName?: string;
     }[]
   >([]); // 分院列表
   const [ifLoading, setIfLoading] = useState(false);
-  const [currentHospName, setCurrentHospName] = useState('欢迎进入医务管理系统');
+  const [currentHospName, setCurrentHospName] = useState(title);
   const { initialState, setInitialState } = useModel('@@initialState');
   const [windowWidth, set_windowWidth] = useState(0);
   const [ifShowLeftBlock, set_ifShowLeftBlock] = useState(true);
@@ -97,7 +110,6 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
   const getSubHospFunc = async () => {
     if (hospSign) {
       const data = await getHospConfigBySign(hospSign);
-
       if ((data as any) instanceof Array) {
         setSubHospList(
           data.map((t) => {
@@ -112,11 +124,11 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
               systemName: t.systemName,
             };
             if (t.hospSign == hospSign) {
-              setCurrentHospName(temp.systemName);
+              setCurrentHospName(temp.systemName || title);
               set_currentSelectedSubHop(temp);
               localStorage.setItem('currentSelectedSubHop', JSON.stringify(temp));
               localStorage.setItem('hospAbbreviation', temp.hospAbbreviation);
-              localStorage.setItem('currentHospName', temp.systemName);
+              localStorage.setItem('currentHospName', temp.systemName || '');
             }
             return temp;
           })
@@ -126,7 +138,6 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
   };
 
   const handleResize = (e: Event) => {
-    // console.log('innerWidth',(e.target as Window).innerWidth);
     set_windowWidth((e.target as Window).innerWidth);
   };
 
@@ -135,7 +146,7 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
   }, [title]);
 
   useEffect(() => {
-    if (windowWidth <= 1000 && windowWidth != 0) {
+    if (windowWidth <= 1000 && windowWidth !== 0) {
       set_ifShowLeftBlock(false);
     } else {
       set_ifShowLeftBlock(true);
@@ -143,37 +154,34 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
   }, [windowWidth]);
 
   useEffect(() => {
-    if (currentSelectedSubHop) {
-      const { loginPic } = currentSelectedSubHop;
-      if (loginPic.length > 0) {
-        const arr = loginPic.split('|');
-        if (arr.length == 2) {
-          changeFavicon(arr[1]);
-        }
+    if (currentSelectedSubHop && currentSelectedSubHop.loginPic && currentSelectedSubHop.loginPic.length > 0) {
+      const arr = currentSelectedSubHop.loginPic.split('|');
+      if (arr.length === 2) {
+        changeFavicon(arr[1]);
       }
     }
   }, [currentSelectedSubHop]);
 
   useEffect(() => {
     if (hospSign) {
-      location.pathname == '/login' && getSubHospFunc();
+      location.pathname === '/login' && getSubHospFunc();
     }
-  }, [hospSign]);
+  }, [hospSign, location.pathname]);
 
   useEffect(() => {
     // 根据hospSign获取分院信息
-    setInitialState((s:any) => ({ ...s, currentSelectedSys: undefined, openedSysLists: [] }));
+    setInitialState((s: any) => ({ ...(s || {}), currentSelectedSys: undefined, openedSysLists: [] }));
 
     window.addEventListener('resize', (e) => handleResize(e)); // 监听窗口大小改变
 
-    const hospSign = history.location.query?.hospSign as string;
-    localStorage.setItem('hospSign', hospSign);
-    set_hospSign(hospSign);
+    const queryHospSign = history.location.query?.hospSign as string;
+    localStorage.setItem('hospSign', queryHospSign);
+    set_hospSign(queryHospSign);
 
     return () => {
       window.removeEventListener('resize', handleResize);
     };
-  }, []);
+  }, [setInitialState]);
 
   const onFinish = async (values: { account: string; password: string }) => {
     setIfLoading(true);
@@ -181,8 +189,12 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
     setIfLoading(false);
 
     if (resp) {
-      const currentSelectedSubHop = JSON.parse(localStorage.getItem('currentSelectedSubHop') || '{}');
-      setInitialState((s: any) => ({ ...s, userData: resp }));
+      const currentSelectedSubHopStr = localStorage.getItem('currentSelectedSubHop') || '{}';
+      const currentSelectedSubHop = JSON.parse(currentSelectedSubHopStr);
+      const customerType = await getHospType();
+      setInitialState((s: any) => ({ ...(s || {}), userData: resp, customerType }));
+      localStorage.setItem('customerType', customerType || '');
+
       if (currentSelectedSubHop.loadType) {
         const lastLoginSysData = await getLastLoginSys({ hospId: currentSelectedSubHop.id, userId: resp.userId });
         if (lastLoginSysData) {
@@ -195,25 +207,31 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
     }
   };
 
+  const loginPicArr = currentSelectedSubHop?.loginPic ? currentSelectedSubHop.loginPic.split('|') : [];
+  const loginTipsArr = currentSelectedSubHop?.loginTips ? currentSelectedSubHop.loginTips.split('|') : [];
+
   return (
     <div className="loginPage">
       <Helmet>
         <title>{currentHospName}</title>
       </Helmet>
 
-      {location.pathname == '/login' ? (
+      {location.pathname === '/login' ? (
         <>
           <Row style={{ height: '100%' }}>
             {ifShowLeftBlock && (
               <Col flex="500px">
                 <div className="left">
                   <div className="topLogo">
-                    {((currentSelectedSubHop?.loginPic).split('|'))[0] && (
-                      <img className="logo" src={((currentSelectedSubHop?.loginPic).split('|'))[0]} alt="康程智医" />
+                    {loginPicArr[0] && (
+                      <img className="logo" src={loginPicArr[0]} alt="康程智医" />
                     )}
-                    {((currentSelectedSubHop?.loginTips.split('|'))[0]) && (
-                      <div className="logoDesc" style={{ borderLeft: ((currentSelectedSubHop?.loginPic).split('|'))[0] ? '1px solid #CFD6E6' : 'none' }}>
-                        {(currentSelectedSubHop?.loginTips.split('|'))[0]}
+                    {loginTipsArr[0] && (
+                      <div
+                        className="logoDesc"
+                        style={{ borderLeft: loginPicArr[0] ? '1px solid #CFD6E6' : 'none' }}
+                      >
+                        {loginTipsArr[0]}
                       </div>
                     )}
                   </div>
@@ -225,8 +243,10 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
               <div className="rightLoginArea">
                 {!ifShowLeftBlock && (
                   <div className="topLogo">
-                    <img className="logo" src={currentSelectedSubHop?.loginPic} alt="康程智医" />
-                    <div className="logoDesc">{(currentSelectedSubHop?.loginTips.split('|'))[0]}</div>
+                    {loginPicArr[0] && <img className="logo" src={loginPicArr[0]} alt="康程智医" />}
+                    {loginTipsArr[0] && (
+                      <div className="logoDesc">{loginTipsArr[0]}</div>
+                    )}
                   </div>
                 )}
 
@@ -271,20 +291,17 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
                   </Form.Item>
                 </Form>
                 <div className="bottomCopyright">
-                  {(currentSelectedSubHop?.loginTips.split('|'))[1]}
-                  <span style={{ paddingLeft: 16 }}>{(currentSelectedSubHop?.loginTips.split('|'))[2]}</span>
+                  {loginTipsArr[1]}
+                  <span style={{ paddingLeft: 16 }}>{loginTipsArr[2]}</span>
                   <a
                     target="_blank"
                     href="https://beian.miit.gov.cn/"
                     style={{ display: 'inline-block', textDecoration: 'none', marginLeft:10,color:'#515866' }}
+                    rel="noreferrer"
                   >
                     滇ICP备2024031095号
                   </a>
                 </div>
-
-                {/* <div className="beian">
-                 
-                </div> */}
               </div>
             </Col>
           </Row>
@@ -296,4 +313,11 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
   );
 };
 
-export default LoginPage;
+// 使用ErrorBoundary包裹LoginPage,使得LoginPage内部的错误能被捕获
+const WrappedLoginPage = () => (
+  <ErrorBoundary>
+    <LoginPage />
+  </ErrorBoundary>
+);
+
+export default WrappedLoginPage;

+ 5 - 3
src/pages/platform/_layout.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2022-01-06 15:25:39
- * @LastEditTime: 2024-10-09 15:57:01
+ * @LastEditTime: 2024-12-10 16:43:30
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/_layout.tsx
@@ -156,10 +156,12 @@ export default function Layout({ children, location, route, history, match, ...r
     set_emptyPageContent(menuItem.description);
   };
 
+  const currentHospName = localStorage.getItem('currentHospName');
+
 
   const checkPermission = (path: any) => {
     const { navData = [], menuData = [] } = initialState || {};
-
+    
     // 检查访问权限
     const hasAccess = checkAccess([...navData, ...menuData], path);
 
@@ -586,7 +588,7 @@ export default function Layout({ children, location, route, history, match, ...r
           }}
         >
           <Helmet>
-            <title>精益管理中台</title>
+            <title>{initialState?.customerType == '2'?currentHospName:'精益管理中台'}</title>
           </Helmet>
 
           <div className="page" style={{ height: 'calc(100vh - 80px)', overflowY: 'scroll' }}>

+ 17 - 16
src/pages/platform/setting/departmentMana/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2024-12-02 14:02:58
+ * @LastEditTime: 2024-12-10 10:24:52
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -22,11 +22,12 @@ import { useEffect, useState } from 'react'
 import { addData, delData, editData, getDepartmentData, getDepartmentType, getRelaHosp, importDepartmentData } from './service';
 
 import './style.less';
+import { useModel } from 'umi';
 
 
 
 export default function DepartmentMana() {
-
+    const { initialState,setInitialState } = useModel('@@initialState');
     const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
     const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
     const [reload, set_reload] = useState(false);
@@ -39,20 +40,20 @@ export default function DepartmentMana() {
 
     const columns = [
         {
-            title: '科室代码',
+            title: initialState?.customerType == '2'?'组织编码':'科室代码',
             dataIndex: 'code',
         },
         {
-            title: '科室名称',
+            title: initialState?.customerType == '2'?'组织名称':'科室名称',
             dataIndex: 'name',
         },
         {
-            title: '院区',
+            title: initialState?.customerType == '2'?'园区':'院区',
             dataIndex: 'hospName',
 
         },
         {
-            title: '类型',
+            title: initialState?.customerType == '2'?'组织类型':'科室类型',
             dataIndex: 'type',
             valueType: 'select',
             fieldProps: {
@@ -144,19 +145,19 @@ export default function DepartmentMana() {
             >
                 <ProFormText
                     name="name"
-                    label="科室名称:"
+                    label={initialState?.customerType == '2'?'组织名称:':'科室名称:'}
                     placeholder="请输入"
-                    rules={[{ required: true, message: '科室名称不能为空!' }]}
+                    rules={[{ required: true, message:initialState?.customerType == '2'?'组织名称不能为空!':'科室名称不能为空!' }]}
                 />
                 <ProFormText
                     name="code"
-                    label="科室代码:"
+                    label={initialState?.customerType == '2'?'组织编码:':'科室代码:'}
                     placeholder="请输入"
-                    rules={[{ required: true, message: '科室代码不能为空!' }]}
+                    rules={[{ required: true, message:initialState?.customerType == '2'?'组织编码不能为空!': '科室代码不能为空!' }]}
                 />
                 <ProFormSelect
                     name="type"
-                    label="类型:"
+                    label={initialState?.customerType == '2'?'组织类型:':'科室类型:'}
                     placeholder="请选择类型"
                     fieldProps={{size:'small'}}
                     rules={[{ required: true, message: '类型不能为空!' }]}
@@ -166,10 +167,10 @@ export default function DepartmentMana() {
                 />
                 <ProFormSelect
                     name="hospId"
-                    label="院区:"
+                    label={initialState?.customerType == '2'?'园区':'院区:'}
                     fieldProps={{size:'small'}}
-                    placeholder="请选择院区"
-                    rules={[{ required: true, message: '院区不能为空!' }]}
+                    placeholder="请选择"
+                    rules={[{ required: true, message: initialState?.customerType == '2'?'园区能为空!':'院区不能为空!' }]}
                     request={async () => {
                         const resp = await getRelaHosp();
                         if (resp) {
@@ -303,7 +304,7 @@ export default function DepartmentMana() {
                     </div>
                     <div className='filterItem' >
                         <span className='label'>检索:</span>
-                        <KCInput placeholder={'请输入科室名称'} style={{ width: 160 }} search allowClear
+                        <KCInput placeholder={initialState?.customerType == '2'?'请输入组织名称!':'请输入科室名称'} style={{ width: 160 }} search allowClear
                             onChange={(e) => {
                                 set_tableDataSearchKeywords(e.target.value);
                                 if (e.target.value.length == 0) {
@@ -320,7 +321,7 @@ export default function DepartmentMana() {
                     </div>
                 </div>
                 <div className='btnGroup'>
-                    {importData('科室')}
+                    {importData(initialState?.customerType == '2'?'组织':'科室')}
                     <UpDataActBtn record type='ADD' />
                 </div>
             </div>

+ 12 - 10
src/pages/platform/setting/hospManage/index.tsx

@@ -1,14 +1,14 @@
 /*
  * @Author: your name
  * @Date: 2022-01-13 15:22:48
- * @LastEditTime: 2024-12-02 14:01:28
+ * @LastEditTime: 2024-12-10 10:15:05
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/hospManage/index.tsx
  */
 
 import { FC, Key, useEffect, useMemo, useState } from 'react';
-import { hospManageModelState, ConnectProps, Loading, connect } from 'umi';
+import { hospManageModelState, ConnectProps, Loading, connect, useModel } from 'umi';
 import { Button, Checkbox, Divider, Drawer, Dropdown, Input, Popconfirm, Switch, Table, Tree, TreeProps, message } from 'antd';
 import KCTable from '@/components/kcTable';
 import type { ProColumns } from '@ant-design/pro-table';
@@ -89,6 +89,7 @@ export function extractAttributeValues(tree: TreeNode, attributeName: keyof Tree
 }
 
 const DrawerActBtn = ({ record }: { record: any }) => {
+  const { initialState,setInitialState } = useModel('@@initialState');
   const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
   const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>(undefined);
   const [drawerTablereload, set_drawerTablereload] = useState(false);
@@ -485,7 +486,7 @@ const DrawerActBtn = ({ record }: { record: any }) => {
     >
       <div className="setApiPermDrawer">
         <div className="topbar">
-          <div className="title">{`院区菜单权限设置(${record.hospName})`}</div>
+          <div className="title">{initialState?.customerType == '2'?`园区菜单权限设置(${record.hospName})`:`院区菜单权限设置(${record.hospName})`}</div>
           <div className="btnGroup">
             <span className={ifFrozze ? 'clearBtn disabled' : 'clearBtn'} onClick={() => clearFunction()}>
               清除功能权限
@@ -710,7 +711,8 @@ const DrawerActBtn = ({ record }: { record: any }) => {
 
 const HospManage: FC<PageProps> = ({ hospManageModel: state, dispatch }) => {
   const { reloadTable } = state;
-
+  const { initialState,setInitialState } = useModel('@@initialState');
+  console.log('initialState?.customerType',initialState?.customerType)
   const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
   const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
   const [tabIds, set_tabIds] = useState<Key[]>([]);
@@ -720,12 +722,12 @@ const HospManage: FC<PageProps> = ({ hospManageModel: state, dispatch }) => {
 
   const columns: ProColumns<TableListItem>[] = [
     {
-      title: '院区ID',
+      title:initialState?.customerType == '2'?'园区ID':'院区ID',
       dataIndex: 'id',
       width:70
     },
     {
-      title: '院区名称',
+      title:initialState?.customerType == '2'?'园区名称':'院区名称',
       dataIndex: 'hospName',
       hideInSearch: false,
       ellipsis:true,
@@ -739,7 +741,7 @@ const HospManage: FC<PageProps> = ({ hospManageModel: state, dispatch }) => {
     //   },
     // },
     {
-      title: '医院标识',
+      title:initialState?.customerType == '2'?'园区标识':'医院标识',
       dataIndex: 'hospSign',
       ellipsis:true
     },
@@ -748,12 +750,12 @@ const HospManage: FC<PageProps> = ({ hospManageModel: state, dispatch }) => {
     //   dataIndex: 'hospAbbreviation',
     // },
     {
-      title: '主院名称',
+      title: initialState?.customerType == '2'?'主园区名称':'主院名称',
       dataIndex: 'parentName',
       ellipsis:true
     },
     {
-      title: '医院等级',
+      title: initialState?.customerType == '2'?'园区等级':'医院等级',
       dataIndex: 'hospitalLevelName',
       ellipsis:true,
       width:90
@@ -763,7 +765,7 @@ const HospManage: FC<PageProps> = ({ hospManageModel: state, dispatch }) => {
     //   dataIndex: 'hospitalType',
     // },
     {
-      title: '医院性质',
+      title: initialState?.customerType == '2'?'园区性质':'医院性质',
       dataIndex: 'hospitalNatureName',
       ellipsis:true,
       width:90

+ 15 - 14
src/pages/platform/setting/hospManage/modals/modal.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2022-01-12 17:11:11
- * @LastEditTime: 2024-10-11 16:52:20
+ * @LastEditTime: 2024-12-09 15:54:33
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/userManage/modal.tsx
@@ -10,7 +10,7 @@
 import React, { useEffect, useRef, useState } from 'react';
 import KCModal from '@/components/KCModal';
 import KCProSelect from '@/components/KCProSelect';
-import { hospManageModelState, Dispatch } from 'umi';
+import { hospManageModelState, Dispatch, useModel } from 'umi';
 
 import { ProFormText, ProFormRadio, ProFormDependency, ProFormDigit } from '@ant-design/pro-form';
 import type { ProColumns } from '@ant-design/pro-table';
@@ -30,6 +30,7 @@ interface ActModalProps extends hospManageModelState {
 type DataSourceType = YoushuAccountsType & { key: number };
 
 const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, currentEdit }) => {
+  const { initialState,setInitialState } = useModel('@@initialState');
   const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
   const [dataSource, setDataSource] = useState<DataSourceType[]>([]);
 
@@ -124,13 +125,13 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
 
   const setModalTitle = () => {
     if (tableAct == TableActType.EDIT) {
-      return '编辑院区';
+      return initialState?.customerType == '2'?'编辑园区':'编辑院区';
     }
     if (tableAct == TableActType.ADD) {
-      return '新增院区';
+      return initialState?.customerType == '2'?'新增园区':'新增院区';
     }
     if (tableAct == TableActType.BINDACCOUNT) {
-      return '院区报告设置';
+      return initialState?.customerType == '2'?'园区报告设置':'院区报告设置';
     }
   };
 
@@ -223,17 +224,17 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
           <ProFormText
             width="md"
             name="hospName"
-            label="医院名称"
+            label={initialState?.customerType == '2'?'园区名称':'医院名称'}
             placeholder="请输入"
             rules={[
               {
                 required: true,
-                message: '请输入医院名称!',
+                message: initialState?.customerType == '2'?'请输入园区名称!':'请输入医院名称!',
               },
             ]}
           />
           <KCProSelect
-            label="是否主院"
+            label={initialState?.customerType == '2'?'是否主园区':'是否主院'}
             width="md"
             name="isHospital"
             fieldProps={{size:'small'}}
@@ -259,7 +260,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               if (isHospital && isHospital == 1) {
                 return (
                   <KCProSelect
-                    label="选择主院"
+                    label={initialState?.customerType == '2'?'选择主园区':'选择主院'}
                     width="md"
                     name="parentId"
                     fieldProps={{
@@ -279,7 +280,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
                     rules={[
                       {
                         required: true,
-                        message: '请选择院区!',
+                        message: initialState?.customerType == '2'?'请选择园区!':'请选择院区!',
                       },
                     ]}
                   />
@@ -288,7 +289,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
             }}
           </ProFormDependency>
           <KCProSelect
-            label="医院等级"
+            label={initialState?.customerType == '2'?'园区等级':'医院等级'}
             width="md"
             name="hospitalLevel"
             request={async () => {
@@ -303,7 +304,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
             ]}
           />
           <KCProSelect
-            label="医院类型"
+            label={initialState?.customerType == '2'?'园区类型':'医院类型'}
             width="md"
             name="hospitalType"
             request={async () => {
@@ -318,7 +319,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
             ]}
           />
           <KCProSelect
-            label="医院性质"
+            label={initialState?.customerType == '2'?'园区性质':'医院性质'}
             width="md"
             name="hospitalNature"
             request={async () => {
@@ -333,7 +334,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
             ]}
           />
 
-          <ProFormText width="md" name="hospSign" label="医院标识" disabled />
+          <ProFormText width="md" name="hospSign" label={initialState?.customerType == '2'?'园区标识':'医院标识'} disabled />
           <ProFormText
             width="md"
             name="hospAbbreviation"

+ 2 - 2
src/pages/platform/setting/indicatorMana/index.tsx

@@ -20,14 +20,14 @@ import TreeDirectory from './TreeDirectory';
 
 import './style.less';
 import { getIndicatorDictionary, IndicatorDictionaryDataType } from '@/service/dictionary';
-import { useLocation } from 'umi';
+import { useLocation, useModel } from 'umi';
 import { KCIMLeftList } from '../../components/KCIMLeftList';
 import KCTable from '@/components/kcTable';
 import { KCInput } from '@/components/KCInput';
 
 
 const IndicatorMana = () => {
-
+  
   const [reloadTable, set_reloadTable] = useState(false);
   const [drawerVisible, set_drawerVisible] = useState(false);
   const [indicateType, set_indicateType] = useState<IndicatorDictionaryDataType[]>([]);

+ 5 - 4
src/pages/platform/setting/pubDicMana/index.tsx

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2023-03-03 11:30:33
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2024-12-02 14:09:41
+ * @LastEditTime: 2024-12-13 15:52:54
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -182,11 +182,9 @@ const PubDicMana = () => {
         <ProFormText name="name" label={tableFileNames.length == 7?`${tableFileNames[0]}:`:"名称:"} placeholder="请输入" rules={[{ required: true, message: '名称不能为空!' }]} />
         <ProFormText name="code" label={tableFileNames.length == 7?`${tableFileNames[1]}:`:"代码:"} placeholder="请输入" rules={[{ required: true, message: '代码不能为空!' }]} />
         <ProFormText name="value" label={tableFileNames.length == 7?`${tableFileNames[2]}:`:"对应值:"} placeholder="请输入" />
-        <ProFormDigit label={tableFileNames.length == 7?`${tableFileNames[3]}:`:"顺序号:"} name={pageType == 1 ? 'dictSort' : 'sort'} rules={[{ required: true, message: '顺序号不能为空!' }]} />
-
         <ProFormRadio.Group
           name={pageType == 1 ? 'dictDefault' : 'defaultFlag'}
-          label={tableFileNames.length == 7?`${tableFileNames[4]}:`:"默认:"}
+          label={tableFileNames.length == 7?`${tableFileNames[3]}:`:"默认:"}
           fieldProps={{
             buttonStyle: 'solid',
           }}
@@ -202,6 +200,9 @@ const PubDicMana = () => {
           ]}
           rules={[{ required: true, message: '默认不能为空!' }]}
         />
+        <ProFormDigit label={tableFileNames.length == 7?`${tableFileNames[4]}:`:"顺序号:"} name={pageType == 1 ? 'dictSort' : 'sort'} rules={[{ required: true, message: '顺序号不能为空!' }]} />
+
+        
         {true && (
           <>
             <ProFormText name="expandOne" label={tableFileNames.length == 7?`${tableFileNames[5]}:`:"扩展一:"} placeholder="请输入" />

+ 20 - 11
src/pages/platform/setting/roleManage/index.tsx

@@ -1,14 +1,14 @@
 /*
  * @Author: your name
  * @Date: 2022-01-13 15:22:48
- * @LastEditTime: 2024-12-02 14:11:50
+ * @LastEditTime: 2024-12-27 14:32:56
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/hospManage/index.tsx
  */
 
 import { FC, Key, useEffect, useState } from 'react';
-import { roleManageModelState, ConnectProps, Loading, connect } from 'umi';
+import { roleManageModelState, ConnectProps, Loading, connect, useModel } from 'umi';
 import { Checkbox, Divider, Dropdown, Input, Popconfirm, Switch, Transfer, TreeProps, Modal } from 'antd';
 import KCTable from '@/components/kcTable';
 import type { ProColumns } from '@ant-design/pro-table';
@@ -59,6 +59,7 @@ const SearchIcon = createFromIconfontCN({
 const selectSystem: { systemId: string; type: number }[] = [];
 
 const DrawerActBtn = ({ record }: { record: any }) => {
+  const { initialState,setInitialState } = useModel('@@initialState');
   const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
   const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>(undefined);
   const [drawerTablereload, set_drawerTablereload] = useState(false);
@@ -702,7 +703,7 @@ const DrawerActBtn = ({ record }: { record: any }) => {
 
 const RoleManage: FC<PageProps> = ({ roleManageModel: state, dispatch }) => {
   const { reloadTable } = state;
-
+  const { initialState,setInitialState } = useModel('@@initialState');
   const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
   const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
 
@@ -713,7 +714,7 @@ const RoleManage: FC<PageProps> = ({ roleManageModel: state, dispatch }) => {
       hideInTable: true,
     },
     {
-      title: '院区名称',
+      title: initialState?.customerType == '2'?'园区名称':'院区名称',
       dataIndex: 'hospName',
       ellipsis:true,
       width:200
@@ -732,18 +733,26 @@ const RoleManage: FC<PageProps> = ({ roleManageModel: state, dispatch }) => {
       title: '备注',
       dataIndex: 'remark',
     },
-    {
-      title: '变更人',
-      dataIndex: 'hospAbbreviation',
-    },
     {
       title: '有数账号',
       dataIndex: 'account',
     },
     {
-      title: '变更日期',
-      dataIndex: 'modifyTime',
-      ellipsis:true
+      title: '数据权限',
+      dataIndex: 'dataPermissionName',
+    },
+    {
+      title: '角色标签',
+      renderText(text, record:any) {
+          const {roleTags = []}  = record;
+          return (<>
+               {
+                roleTags.map((a:any,i:number)=>(<span style={{
+                  display:'inline-flex',padding:'2px 5px',fontSize:12,background:'#EEF3FA',borderRadius:4,color:'#525866',marginRight:4
+                }}>{a.labelName}</span>))
+               }
+          </>)
+      },
     },
     {
       title: '操作',

+ 98 - 25
src/pages/platform/setting/roleManage/modals/modal.tsx

@@ -1,26 +1,38 @@
 import React from 'react';
 import KCModal from '@/components/KCModal';
 import KCProSelect from '@/components/KCProSelect';
-import { roleManageModelState, Dispatch } from 'umi';
+import { roleManageModelState, Dispatch, useModel } from 'umi';
 
 import { ProFormText, ProFormTextArea } from '@ant-design/pro-form';
 import { getHospList, getShareHospList } from '@/service/hospList';
-import { AddUsersDataType, getYoushuUsers } from '@/service/user';
+import { AddUsersDataType, getUserRelaSeletData, getYoushuUsers } from '@/service/user';
 
 import { TableActType } from '..';
 import { Form } from 'antd';
 import MenuEditer from '@/pages/platform/components/menuEditer/menu';
 import UserEditer from '@/pages/platform/components/usersEditer';
+import { getSysParamsByCode } from '@/service';
+import { KcimCenterSysId } from '@/constant';
+import { getDictByDictTypeAndSysid } from '@/service/dictionary';
 
 interface ActModalProps extends roleManageModelState {
   dispatch: Dispatch | undefined;
 }
 
+function checkRoleTagsIsObjArr(roleTags:any[]) {
+  if (typeof roleTags[0] === 'object' && roleTags[0] !== null && !Array.isArray(roleTags[0])) {
+    return true
+  }
+  return false
+}
+
 const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, currentEdit, hospId }) => {
 
+  const { initialState, setInitialState } = useModel('@@initialState');
+  // const temp = {...currentEdit,roleTags:[{labelCode:'001',labelName:'后勤'}]}
   const setInitialValues = () => {
     if (tableAct === TableActType.EDIT) {
-      return { ...currentEdit };
+      return { ...currentEdit, dataPermission: currentEdit?.dataPermissionCode ?? null, roleTags: currentEdit?.roleTags?.map((a) => a.labelCode) ?? [] };
     }
     if (tableAct === TableActType.ADD) {
       return { hospId: hospId };
@@ -42,26 +54,44 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
   };
 
   const onFinishHandle = (data: any & AddUsersDataType) => {
-    console.log({initialValues});
-    
 
-    if (tableAct === TableActType.ADD) {
-      dispatch &&
-        dispatch({
-          type: 'roleManageModel/postAddData',
-          payload: data,  // 使用合并后的数据
-        });
+    try {
+
+      if (tableAct === TableActType.ADD) {
+        const { dataPermission, ...rest } = data;
+        dispatch &&
+          dispatch({
+            type: 'roleManageModel/postAddData',
+            payload: {
+              ...rest,
+              dataPermissionCode: data.dataPermission.value,
+              dataPermissionName: data.dataPermission.label,
+              roleTags: data.roleTags.map((a: any) => ({ labelCode: a.value, labelName: a.label })),
+            },  // 使用合并后的数据
+          });
+      }
+
+      if (tableAct === TableActType.EDIT || tableAct === TableActType.EDITMENU || tableAct === TableActType.EDITRELAUSER) {
+        const { dataPermission,roleTags, ...rest } = data;
+        const flag = checkRoleTagsIsObjArr(roleTags);
+        dispatch &&
+          dispatch({
+            type: 'roleManageModel/postEditData',
+            payload: {
+              ...rest,
+              dataPermissionCode: (dataPermission && typeof dataPermission == 'string') ? data.dataPermissionCode : dataPermission.value,
+              dataPermissionName: (dataPermission && typeof dataPermission == 'string') ? data.dataPermissionName : dataPermission.label,
+              roleTags:flag?data.roleTags.map((a: any) => ({ labelCode: a.value, labelName: a.label })):currentEdit?.roleTags,
+            }
+          });
+      }
+
+      return true
+
+    } catch (error) {
+      console.log('add or edit error', error);
     }
 
-    if (tableAct === TableActType.EDIT || tableAct === TableActType.EDITMENU || tableAct === TableActType.EDITRELAUSER) {
-      dispatch &&
-        dispatch({
-          type: 'roleManageModel/postEditData',
-          payload: data,  // 使用合并后的数据
-        });
-    }
-
-    return true;
   };
 
   const setModalTitle = () => {
@@ -79,7 +109,9 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
     }
   };
 
-  
+
+
+
 
   return (
     <KCModal
@@ -92,7 +124,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
       labelCol={{
         span: 5,
       }}
-      onFinish={async (data) => onFinishHandle({...data})}
+      onFinish={async (data) => onFinishHandle({...currentEdit, ...data })}
     >
       {tableAct === TableActType.EDITMENU && (
         <Form.Item name="bindMenuIds">
@@ -109,11 +141,11 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
       {(tableAct === TableActType.ADD || tableAct === TableActType.EDIT) && (
         <>
           <KCProSelect
-            label="选择院区"
+            label={initialState?.customerType == '2' ? '选择园区' : '选择院区'}
             width="md"
             name="hospId"
             disabled
-            fieldProps={{size:'small'}}
+            fieldProps={{ size: 'small' }}
             request={async () => {
               const hospList = await getShareHospList();
               if (hospList) {
@@ -137,7 +169,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               },
             ]}
           />
-           <ProFormText
+          <ProFormText
             width="md"
             name="roleCode"
             label="角色编码"
@@ -153,6 +185,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
           <KCProSelect
             label="关联有数账号"
             width="md"
+            fieldProps={{ size: 'small' }}
             name="youshuUserId"
             request={async () => {
               const resp = await getYoushuUsers();
@@ -165,6 +198,46 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               return [];
             }}
           />
+          <KCProSelect
+            label="数据权限"
+            width="md"
+            name="dataPermission"
+            fieldProps={{
+              size: 'small',
+              labelInValue: true,
+            }}
+            request={async () => {
+              // const resp = await getYoushuUsers();
+              const resp = await getDictByDictTypeAndSysid(KcimCenterSysId, 'ROLE_DATA_PERMISSIONS_DIC');
+              if (resp) {
+                return resp.dataVoList.map((t: any) => ({
+                  label: t.name,
+                  value: t.code,
+                }));
+              }
+              return [];
+            }}
+          />
+          <KCProSelect
+            label="角色标签"
+            width="md"
+            name="roleTags"
+            fieldProps={{
+              size: 'small',
+              labelInValue: true,
+              mode: 'tags'
+            }}
+            request={async () => {
+              const resp = await getDictByDictTypeAndSysid(KcimCenterSysId, 'ROLE_LABEL_DIC');
+              if (resp) {
+                return resp.dataVoList.map((t: any) => ({
+                  label: t.name,
+                  value: t.code,
+                }));
+              }
+              return [];
+            }}
+          />
 
           <ProFormTextArea name="remark" label="备注" placeholder="请输入名称" width="md" fieldProps={{}} />
         </>

+ 2 - 0
src/pages/platform/setting/roleManage/model.ts

@@ -17,6 +17,8 @@ import {
 } from '@/service/role';
 import { getMainHosp } from '@/service/hospList';
 import type { RoleItemType as TableListItem } from '@/service/role';
+import { getDictByDictTypeAndSysid } from '@/service/dictionary';
+import { KcimCenterSysId } from '@/constant';
 
 enum TableActType {
   NOACT,

+ 52 - 37
src/pages/platform/setting/userManage/index.tsx

@@ -1,15 +1,15 @@
 /*
  * @Author: your name
  * @Date: 2022-01-11 09:43:18
- * @LastEditTime: 2024-12-02 14:15:06
+ * @LastEditTime: 2024-12-18 10:04:36
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/userManage/index.tsx
  */
 
 import { FC, useEffect, useState } from 'react';
-import { userManageModelState, ConnectProps, Loading, connect } from 'umi';
-import { Button, Divider, Popconfirm } from 'antd';
+import { userManageModelState, ConnectProps, Loading, connect, useModel } from 'umi';
+import { Button, Divider, Popconfirm, Popover, Tooltip } from 'antd';
 import KCTable from '@/components/kcTable';
 import type { ProColumns } from '@ant-design/pro-table';
 import { getUserRelaSeletData, getUsers, UserRelaSeletDataListType, UserRelaSeletDataType } from '@/service/user';
@@ -38,7 +38,7 @@ interface PageProps extends ConnectProps {
 
 const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
   const { reloadTable } = state;
-
+  const { initialState, setInitialState } = useModel('@@initialState');
   const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
   const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
 
@@ -46,10 +46,10 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
 
   const columns: ProColumns<TableListItem>[] = [
     {
-      title: '院区',
+      title: initialState?.customerType == '2' ? '园区' : '院区',
       dataIndex: 'hospName',
-      ellipsis:true,
-      width:210
+      ellipsis: true,
+      width: 210
     },
     {
       title: '姓名',
@@ -62,7 +62,7 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
       hideInSearch: false,
     },
     {
-      title: '电话',
+      title: '联系电话',
       dataIndex: 'phoneNumber',
     },
     {
@@ -82,26 +82,41 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
       width: 220,
       key: 'option',
       valueType: 'option',
-      render: (text, record) => [
-        <a key="link" onClick={() => editHandle(record)}>
-          编辑
-        </a>,
-        <Divider key="1" type="vertical" style={{ margin: '0 3px' }} />,
-        <Popconfirm
-          title="是否确定删除?"
-          onConfirm={() => delHandle(record)}
-          // onCancel={cancel}
-          okText="确定"
-          cancelText="取消"
-          key="link2"
-        >
-          <a>删除</a>
-        </Popconfirm>,
-        <Divider key="2" type="vertical" style={{ margin: '0 3px' }} />,
-        <a key="link3" onClick={() => resetUserPaswdHandle(record)}>
-          重置密码
-        </a>,
-      ],
+      render: (text, record) => {
+
+        const getEditBtn = () => {
+          const { isEdit } = record;
+          if (!isEdit) {
+            return [
+              <a key="link" onClick={() => editHandle(record)}>编辑</a>,
+              <Divider key="1" type="vertical" style={{ margin: '0 3px' }} />,
+              <Popconfirm
+                title="是否确定删除?"
+                onConfirm={() => delHandle(record)}
+                // onCancel={cancel}
+                okText="确定"
+                cancelText="取消"
+                key="link2"
+              >
+                <a>删除</a>
+              </Popconfirm>,
+            ]
+          } else {
+            return [
+              <Tooltip title='第三方人员不可编辑!'><span style={{ cursor: 'not-allowed', color: 'rgb(176 181 189)' }}>编辑</span></Tooltip>,
+              <Divider key="1" type="vertical" style={{ margin: '0 3px' }} />,
+              <Tooltip title='第三方人员不可编辑!'><span style={{ cursor: 'not-allowed', color: 'rgb(176 181 189)' }}>删除</span></Tooltip>,
+            ]
+          }
+        }
+        return [
+          ...getEditBtn(),
+          <Divider key="2" type="vertical" style={{ margin: '0 3px' }} />,
+          <a key="link3" onClick={() => resetUserPaswdHandle(record)}>
+            重置密码
+          </a>,
+        ]
+      }
     },
   ];
 
@@ -197,7 +212,7 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
   const tableDataSearchHandle = (paramName: string) => {
     set_tableDataFilterParams({
       ...tableDataFilterParams,
-      current:1,
+      current: 1,
       [`${paramName}`]: tableDataSearchKeywords,
     });
   };
@@ -271,7 +286,7 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
       <div className="toolBar">
         <div className="filter">
           <div className="filterItem" style={{ marginRight: 16 }}>
-            <span className="label">科室:</span>
+            <span className="label">{initialState?.customerType == '2' ? '组织:' : '科室:'}</span>
             <ProFormSelect
               name="departmentId"
               noStyle
@@ -285,12 +300,12 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
                 return [];
               }}
               fieldProps={{
-                size:'small',
+                size: 'small',
                 showSearch: true,
                 onChange: (val) => {
                   set_tableDataFilterParams({
                     ...tableDataFilterParams,
-                    current:1,
+                    current: 1,
                     departmentId: val,
                   });
                 },
@@ -309,7 +324,7 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
                 if (e.target.value.length == 0) {
                   set_tableDataFilterParams({
                     ...tableDataFilterParams,
-                    current:1,
+                    current: 1,
                     name: '',
                   });
                 }
@@ -333,15 +348,15 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
         reload={reloadTable}
         params={tableDataFilterParams}
         newVer
-        scroll={{y:`calc(100vh - 255px)`}}
+        scroll={{ y: `calc(100vh - 255px)` }}
         expandable={{
           expandedRowRender: (record) => (
             <div className="userExpandInfo">
-              <span>进院时间:{record.entryTime}</span>
-              <span>手机号:{record.phoneNumber}</span>
+              {initialState?.customerType == '2' ? <span>入职时间:{record.entryTime}</span> : <span>入职时间:{record.entryTime}</span>}
+              {initialState?.customerType == '2' ? <span>联系电话:{record.phoneNumber}</span> : <span>联系电话:{record.phoneNumber}</span>}
               <span>所学专业:{record.major}</span>
               <span>资格证号:{record.qualificationCertificateNo}</span>
-              <span>医师级别:{record.doctorLevel}</span>
+              {initialState?.customerType == '2' ? <span>执业级别:{record.doctorLevel}</span> : <span>医师级别:{record.doctorLevel}</span>}
               <span>执业证号:{record.practiceCertificateNo}</span>
               <span>执业类别:{record.practiceSubject}</span>
               <span>执业科目:{record.practiceCate}</span>

+ 11 - 11
src/pages/platform/setting/userManage/modal.tsx

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2022-01-12 17:11:11
- * @LastEditTime: 2024-11-26 17:59:43
+ * @LastEditTime: 2024-12-10 10:19:10
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/userManage/modal.tsx
@@ -11,7 +11,7 @@ import React, { useEffect, useState } from 'react';
 import KCModal from '@/components/KCModal';
 import KCProSelect from '@/components/KCProSelect';
 import { message, Button, Spin, Upload, UploadProps } from 'antd';
-import { userManageModelState, Dispatch } from 'umi';
+import { userManageModelState, Dispatch, useModel } from 'umi';
 import { ProFormDateTimePicker, ProFormDependency, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
 import { getShareHospList } from '@/service/hospList';
 import { AddUsersDataType, getUserRelaSeletData, uploadAvatar, UserRelaSeletDataListType, UserRelaSeletDataType } from '@/service/user';
@@ -36,7 +36,7 @@ interface ActModalProps extends userManageModelState {
 const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
 
 const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, currentEditUser }) => {
-
+  const { initialState,setInitialState } = useModel('@@initialState');
   const [avatarUrl, setAvatarUrl] = useState<string>('');
   const [loadAvatar, setLoadAvatar] = useState(false);
   const [ifCheckPhoneNumber, set_ifCheckPhoneNumber] = useState(false);
@@ -262,7 +262,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               </div>
               <div className="formItem">
                 <KCProSelect
-                  label="所属院区:"
+                  label={initialState?.customerType == '2'?'所属园区:':'所属院区:'}
                   width="md"
                   name="hospId"
                   fieldProps={{ showSearch: true, size: 'small' }}
@@ -279,7 +279,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
                   rules={[
                     {
                       required: true,
-                      message: '请选择院区!',
+                      message:initialState?.customerType == '2'?'请选择园区!':'请选择院区!',
                     },
                   ]}
                 />
@@ -287,7 +287,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               <div className="formItem">
                 <ProFormSelect
                   name="departmentId"
-                  label="科室:"
+                  label={initialState?.customerType == '2'?'组织:':'科室:'}
                   request={async () => {
                     const resp = await getDepartmentData({ pageSize: 1000 });
                     if (resp) {
@@ -304,7 +304,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
                 />
               </div>
               <div className="formItem">
-                <ProFormSelect name="userCate" label="人员类别:" fieldProps={{ showSearch: true, size: 'small' }} options={setSelectorData('PERSONNEL_CATEGORY').list} placeholder="请选择" />
+                <ProFormSelect name="userCate" label={initialState?.customerType=='2'?'员工类别:':'人员类别:'} fieldProps={{ showSearch: true, size: 'small' }} options={setSelectorData('PERSONNEL_CATEGORY').list} placeholder="请选择" />
               </div>
 
               <div className="formItem">
@@ -371,12 +371,12 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
               <div className="formItem">
                 <ProFormText
                   name="phoneNumber"
-                  label="手机号:"
+                  label={initialState?.customerType == '2'?'联系电话:':'联系电话:'}
                   placeholder="请输入"
                   rules={ifCheckPhoneNumber?[
                     {
                       required:true,
-                      message: <span style={{fontSize:12,paddingLeft:50}}>请输入手机号</span>,
+                      message: <span style={{fontSize:12,paddingLeft:50}}>请输入联系电话</span>,
                     },
                     {
                       pattern: /^1[3-9]\d{9}$/,
@@ -393,7 +393,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
                   ]:[
                     {
                       required:false,
-                      message: "请输入手机号",
+                      message: "请输入",
                     },
                   ]}
                 />
@@ -469,7 +469,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
                     <div className="formItem" style={{ position: 'relative', top: -62 }}>
                       <ProFormSelect
                         name="doctorLevel"
-                        label="医师:"
+                        label={initialState?.customerType == '2'?'执业级别:':'医师级别:'}
                         fieldProps={{ showSearch: true, size: 'small' }}
                         options={setSelectorData('PHYSICIAN_TYPE').list}
                         placeholder="请选择"

+ 8 - 1
src/service/dictionary.ts

@@ -2,7 +2,7 @@
  * @Author: code4eat awesomedema@gmail.com
  * @Date: 2022-07-06 11:46:24
  * @LastEditors: code4eat awesomedema@gmail.com
- * @LastEditTime: 2023-01-10 13:16:27
+ * @LastEditTime: 2024-12-27 13:46:30
  * @FilePath: /KC-MiddlePlatform/src/service/dictionary.ts
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -45,3 +45,10 @@ export const getIndicatorDictionary = async () => {
     method: 'GET',
   });
 };
+
+export const getDictByDictTypeAndSysid = async (systemId: string,dictType:string) => {
+  return request('/centerSys/sysdictdata/getDictByDictType', {
+    method: 'GET',
+    params: { dictType,systemId },
+  });
+};

+ 4 - 1
src/service/role.ts

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2022-01-18 14:56:29
- * @LastEditTime: 2023-09-15 15:01:04
+ * @LastEditTime: 2024-12-27 14:43:38
  * @LastEditors: code4eat awesomedema@gmail.com
  * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * @FilePath: /KC-MiddlePlatform/src/service/role.ts
@@ -20,6 +20,9 @@ export type RoleItemType = {
   modifyTime: string;
   remark: string;
   hospId: number;
+  dataPermissionCode?:string;
+  dataPermissionName?:string;
+  roleTags?:any[]
 };
 
 type GetAllRolesType = { list: RoleItemType[] } & TableResponseDataType;