@@ -1,7 +1,7 @@
/*
* @Author: your name
* @Date: 2022-01-07 10:04:20
- * @LastEditTime: 2023-03-21 09:31:27
+ * @LastEditTime: 2023-12-07 10:49:07
* @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
@@ -17,7 +17,7 @@ export default defineConfig({
nodeModulesTransform: {
type: 'none',
},
- title:false,
+ title: false,
publicPath: '/',
dva: {
immer: true,
@@ -30,11 +30,12 @@ export default defineConfig({
lessLoader: {
- modifyVars: { '@ant-prefix': 'kcmp-ant','root-entry-name': 'default' },
- }, //
+ modifyVars: { '@ant-prefix': 'kcmp-ant', 'root-entry-name': 'default' },
+ },
+
theme: {
'@primary-color': '#3376FE',
- '@primary-color-hover':'#3376FE',
+ '@primary-color-hover': '#3376FE',
// '@root-entry-name':'root-entry-name'
routes: [
@@ -45,6 +46,11 @@ export default defineConfig({
{
path: '/app1',
microApp: 'app1',
+ // access: 'canVisitThisApp'
+ microAppProps: {
+ autoSetLoading: true,
+ autoCaptureError: true,
// {
// path: '/costMana',
@@ -53,14 +59,64 @@ export default defineConfig({
path: '/PFMBackC',
microApp: 'PFMBackC',
path: '/reviewMana',
microApp: 'reviewMana',
path: '/budgetManaSystem',
microApp: 'budgetManaSystem',
+ // wrappers: [
+ // '@/wrappers/auth',
+ // ],
+ {
+ path: '/pfmBackMana',
+ microApp: 'pfmBackMana',
+ path: '/CostAccountingSys',
+ microApp: 'CostAccountingSys',
+ //loader: (loading:boolean) => <div>loading</div>,
+ path: '/devServer',
+ microApp: 'devServer',
+ path: '/personnelManaSystem',
+ microApp: 'personnelManaSystem',
path: '/channelIndex/channelIndexOne',
@@ -68,11 +124,11 @@ export default defineConfig({
path: '/index',
- title:'欢迎进入医管平台',
+ title: '欢迎进入医管平台',
component: '@/pages/index/index.tsx',
- title:'精益管管理中台',
+ title: '精益管管理中台',
path: '/platform',
component: '@/pages/platform/_layout.tsx',
@@ -81,122 +137,67 @@ export default defineConfig({
component: '@/pages/platform/sqlediter/index.tsx',
- path: '/platform/setting/userManage',
- component: '@/pages/platform/setting/userManage/index.tsx',
- },
- {
- path: '/platform/setting/hospManage',
- component: '@/pages/platform/setting/hospManage/index.tsx',
- path: '/platform/setting/menuManage',
- component: '@/pages/platform/setting/menuManage/index.tsx',
- path: '/platform/setting/roleManage',
- component: '@/pages/platform/setting/roleManage/index.tsx',
- // {
- // path: '/platform/setting/reports',
- // component: '@/pages/platform/setting/reports/index.tsx',
- // },
- path: '/platform/setting/departmentMana',
- component: '@/pages/platform/setting/departmentMana/index.tsx',
- path: '/platform/setting/pubDicTypeMana',
- component: '@/pages/platform/setting/pubDicTypeMana/index.tsx',
- path: '/platform/setting/pubDicMana',
- component: '@/pages/platform/setting/pubDicMana/index.tsx',
- path: '/platform/setting/indicatorMana',
- component: '@/pages/platform/setting/indicatorMana/index.tsx',
- path: '/platform/setting/paramsMana',
- component: '@/pages/platform/setting/paramsMana/index.tsx',
- path: '/platform/setting/systemNavMana',
- component: '@/pages/platform/setting/systemNavMana/index.tsx',
- path: '/platform/setting/notificationTemplate',
- component: '@/pages/platform/setting/notificationTemplate/index.tsx',
-
- path: '/platform/setting/reports/0',
- component: '@/pages/platform/setting/reports/index.tsx',
- path: '/platform/setting/reports/1',
- path: '/platform/setting/reports/2',
- path: '/platform/setting/reports/3',
- path: '/platform/setting/reports/4',
- path: '/platform/setting/reports/5',
- path: '/platform/setting/reports/6',
- path: '/platform/setting/reports/7',
- path: '/platform/setting/reports/8',
- path: '/platform/setting/reports/9',
- path: '/platform/setting/reports/10',
- path: '/platform/setting/reports/11',
- path: '/platform/setting/reports/12',
- path: '/platform/setting/reports/13',
- path: '/platform/setting/reports/14',
- path: '/platform/setting/reports/15',
+ path: '/platform/setting',
+ routes: [
+ path: '/platform/setting/userManage',
+ component: '@/pages/platform/setting/userManage/index.tsx',
+ path: '/platform/setting/hospManage',
+ component: '@/pages/platform/setting/hospManage/index.tsx',
+ path: '/platform/setting/menuManage',
+ component: '@/pages/platform/setting/menuManage/index.tsx',
+ path: '/platform/setting/roleManage',
+ component: '@/pages/platform/setting/roleManage/index.tsx',
+ // {
+ // path: '/platform/setting/reports',
+ // component: '@/pages/platform/setting/reports/index.tsx',
+ // },
+ path: '/platform/setting/departmentMana',
+ component: '@/pages/platform/setting/departmentMana/index.tsx',
+ path: '/platform/setting/pubDicTypeMana',
+ component: '@/pages/platform/setting/pubDicTypeMana/index.tsx',
+ path: '/platform/setting/hospParamsMana',
+ component: '@/pages/platform/setting/hospParamsMana/index.tsx',
+ path: '/platform/setting/pubDicMana/:type',
+ component: '@/pages/platform/setting/pubDicMana/index.tsx',
+ path: '/platform/setting/indicatorMana',
+ component: '@/pages/platform/setting/indicatorMana/index.tsx',
+ path: '/platform/setting/paramsMana',
+ component: '@/pages/platform/setting/paramsMana/index.tsx',
+ path: '/platform/setting/systemNavMana',
+ component: '@/pages/platform/setting/systemNavMana/index.tsx',
+ path: '/platform/setting/notificationTemplate',
+ component: '@/pages/platform/setting/notificationTemplate/index.tsx',
+ path: '/platform/setting/kcClassification',
+ component: '@/pages/platform/setting/kcClassification/index.tsx',
+ ],
],
path: '/personalCenter',
@@ -206,6 +207,7 @@ export default defineConfig({
+ // hash:true,
proxy: proxy[REACT_APP_ENV || 'dev'],
manifest: {
basePath: '/',
@@ -1,7 +1,11 @@
* @Date: 2022-01-07 10:00:52
+<<<<<<< HEAD
* @LastEditTime: 2023-04-20 13:31:09
+=======
+ * @LastEditTime: 2024-03-18 18:04:31
+>>>>>>> dev
* @FilePath: /KC-MiddlePlatform/config/proxy.ts
@@ -14,19 +18,26 @@
const proxy: { [key: string]: any } = {
dev: {
- '/master': {
- target: 'http://47.97.190.5:7004',
- //target: 'http://118.31.245.65:7005/',
+ //绩效管理
+ '/gateway': {
+ //target: 'http://47.96.149.190:5000',
+ target: 'http://120.27.235.181:5000',
changeOrigin: true,
// pathRewrite: { '^/master': '' },
+ //老版评审管理
'/api': {
- target: 'http://47.97.190.5:8804/',
+ target: 'http://120.27.235.181:8083/',
pathRewrite: { '^/api': '' },
+ //新版评审管理
'/view': {
target: 'http://47.97.190.5:8807',
+ target: 'http://120.27.235.181:8085/',
// pathRewrite: { '^/view': '' },
@@ -1,15 +1,16 @@
import { useState } from 'react';
import { PageLoading } from '@ant-design/pro-layout';
-import { notification, Modal } from 'antd';
-import { RequestConfig, history, useModel } from 'umi';
+import { notification, Modal, message } from 'antd';
+import { RequestConfig, history } from 'umi';
import type { RequestOptionsInit } from 'umi-request';
-import { getHospSubSystemList, UserDataType } from '@/service/login';
+import { UserDataType, getQiankunMicroApps } from '@/service/login';
import { BasicLayoutProps } from '@ant-design/pro-layout';
import { logoutHandle } from './global';
import { Platforms } from './constant';
import { SpacicalPageParamsType } from './typings';
+window.isParentApp = true;
const loginPath = '/login';
@@ -34,7 +35,7 @@ type InitialStateType = {
openedSysLists?: TopBar.Tab[]; //当前已打开的系统列表
currentSelectedSys?: TopBar.Tab; //当前选中的tab
logout?: () => Promise<boolean>;
- childAppIsShowMenu?:boolean;
+ childAppIsShowMenu?: boolean;
spacicalPageParamsType?: SpacicalPageParamsType[];
getHospSubSystemListFunc?: () => Promise<any[]>;
};
@@ -59,16 +60,16 @@ export async function getInitialState(): Promise<InitialStateType> {
//获取当前账号所有子应用列表
const getHospSubSystemListFunc = async () => {
- const data = await getHospSubSystemList();
- if (data) {
- const _data = data.map((t) => ({
- ...t,
- icon: getAppIcon(t.name),
- path: t.path,
- }));
- return _data;
- }
+ // const data = await getHospSubSystemList();
+ // if (data) {
+ // const _data = data.map((t) => ({
+ // ...t,
+ // icon: getAppIcon(t.name),
+ // path: t.path,
+ // }));
+ // return _data;
+ // }
return [];
@@ -105,42 +106,59 @@ const requestInterceptorsHandle = (url: string, options: RequestOptionsInit) =>
authHeader.token = token;
}
return {
- url: `/master${url}`,
- options: { ...options, interceptors: true, headers: authHeader,timeout:100000000, },
+ url: `/gateway${url}`,
+ options: { ...options, interceptors: true, headers: authHeader, timeout: 100000000 },
const responseInterceptorsHandle = async (response: Response, options: RequestOptionsInit) => {
+ const { url, method } = options;
const _response: {
+ errorMessage: any;
+ message: any;
data?: any;
status: number;
+ errorCode?: number;
success?: boolean;
msg?: string;
} = await response.clone().json();
+ if (_response.errorCode == 401) {
+ Modal.confirm({
+ title: '抱歉,你的登录已过期,请重新登录!',
+ okText: '确定',
+ cancelText: '取消',
+ maskClosable: false,
+ // cancelButtonProps:
+ onOk: () => {
+ logoutHandle();
+ return Promise.resolve(true);
+ });
+ return;
+ }
if (_response.status == 200) {
- if (_response.data) {
- return _response.data;
+ if (url != '/centerSys/menu/checkKeygen' && method == 'POST') {
+ message.success({
+ content: `操作成功!`,
+ duration: 1,
- notification.success({
- message: `操作成功!`,
- });
- return {
- status: _response.status,
- success: true,
- };
+ if (_response.data != null || _response.data != undefined) {
+ return _response.data;
+ } else {
+ return true;
} else {
+ console.log({ _response });
notification.error({
- message:`${_response.msg}`,
+ message: '错误:',
+ description: `${_response.msg ? _response.msg : _response.message ? _response.message : _response.errorMessage}`,
});
- return false
+ return false;
@@ -161,16 +179,18 @@ interface ResponseErr extends Error {
const errorHandlerFunc = (error: ResponseErr) => {
try {
const { info } = error;
- const { errorCode , errorMessage } = info;
- if (errorCode == 499) {
+ const { errorCode, errorMessage } = info;
+ console.log({ info });
+ if (errorCode == 499 || errorCode == 401) {
//token过期
Modal.confirm({
title: '抱歉,你的登录已过期,请重新登录!',
- // closable:false,
maskClosable: false,
// cancelButtonProps:
onOk: () => {
@@ -186,9 +206,11 @@ const errorHandlerFunc = (error: ResponseErr) => {
message: ` ${errorCode}:出现错误!`,
description: errorMessage,
+ } else if (false) {
- message: ` ${errorCode}:${errorMessage}`,
+ message: '错误',
+ description: ` ${errorCode}:${errorMessage}`,
} catch (err) {
@@ -203,7 +225,6 @@ export const request: RequestConfig = {
timeout: 10000,
errorConfig: {
adaptor: (resData) => {
if (!resData.success && resData.status != 200) {
...resData,
@@ -230,44 +251,70 @@ export const request: RequestConfig = {
// 从接口中获取子应用配置,export 出的 qiankun 变量是一个 promise
-export const qiankun = fetch('/config').then(() => ({
- // 注册子应用信息
- apps: [
- // name: 'microApp', // 唯一 id
- // entry: '//localhost:8808', // 开发
- name: 'app1', // 唯一 id
- entry: '//47.97.190.5:8804', //测试
- name: 'reviewMana', // 唯一 id
- //entry: '//47.97.190.5:8807', //线上
- entry: '//localhost:8804', // 开发
- // name: 'budgetManaSystem', // 唯一 id
- // //entry: '//localhost:8001'
- // entry: '//112.124.59.133:5000/perform/', // 开发
- // name: 'PFMBackC', // 唯一 id
- // entry: '//112.124.59.133:5000/pfmManager/index.html'
- // //entry: '//112.124.59.133:5000/perform/', // 开发
- ],
- // 完整生命周期钩子请看 https://qiankun.umijs.org/zh/api/#registermicroapps-apps-lifecycles
- lifeCycles: {
- afterMount: (props: any) => {},
- // 支持更多的其他配置,详细看这里 https://qiankun.umijs.org/zh/api/#start-opts
-}));
+export const qiankun = async () => {
+ console.log('process.env', process.env);
+ const { NODE_ENV } = process.env;
+ //NODE_ENV == 'development'
+ if (NODE_ENV == 'development') {
+ return {
+ apps: [
+ // name: 'microApp', // 唯一 id
+ // entry: '//localhost:8808', // 开发
+ // name: 'app1', // 唯一 id
+ // entry: '//120.27.235.181:8804', //测试
+ // name: 'reviewMana', // 唯一 id
+ // entry: '//120.27.235.181:5000/pfmview/',
+ // //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: 'pfmBackMana', // 唯一 id
+ //entry: '//localhost:8001'
+ entry: '//120.27.235.181:5000/pfmManager/', // 开发
+ name: 'CostAccountingSys', // 唯一 id
+ entry: '//localhost:8001',
+ //entry: '//120.27.235.181:5000/costAccount/', // 开发
+ // name: 'personnelManaSystem', // 唯一 id
+ // entry: '//192.168.0.118:8005'
+ // //entry: '//120.27.235.181:5000/costAccount/', // 开发
+ // name:'devServer',
+ // entry: '//localhost:8005'
+ };
+ const resp = await getQiankunMicroApps();
+ if (resp) {
+ let apps = resp.list ? resp.list : resp;
+ apps: [...apps],
+};
//向子应用透传
export function useQiankunStateForSlave() {
const [masterState, setMasterState] = useState({});
@@ -276,37 +323,45 @@ export function useQiankunStateForSlave() {
+// //@/pages/platform/setting/reports/index
+export function patchRoutes({ routes }: { routes: any }) {
+ const treeLoop = (treeData: any) => {
+ if (treeData.path.indexOf('/platform') != -1) {
+ if (treeData.routes) {
+ const paths = [...new Array(100).keys()].map((a, index) => ({
+ path: `${treeData.path == '/' ? '' : treeData.path}/reports/${index}`,
+ exact: true,
+ component: require('@/pages/platform/setting/reports/index.tsx').default,
+ }));
+ const lanhuPagePaths = [...new Array(100).keys()].map((a, index) => ({
+ path: `${treeData.path == '/' ? '' : treeData.path}/static/${index}`,
+ component: require('@/pages/platform/setting/static/index.tsx').default,
+ //console.log({paths});
+ paths.forEach((a: any) => {
+ treeData.routes.push(a);
+ lanhuPagePaths.forEach((a: any) => {
-//@/pages/platform/setting/reports/index
-export function patchRoutes({ routes }:{routes:any}) {
- const paths = [...new Array(100).keys()].map((a,index)=>({
- path: `/platform/setting/reports/${15+(index+1)}`,
- exact: true,
- component: require('@/pages/platform/setting/reports/index.tsx').default,
- const treeLoop = (treeData:any)=>{
- //console.log({treeData})
- if(treeData.path == '/platform'){
- paths.forEach((a:any)=>{
- treeData.routes.push(a);
- })
- return;
- }else{
- if(treeData.routes&&treeData.routes.length>0){
- treeData.routes.forEach((a:any)=>{
- treeLoop(a);
+ if (treeData.routes && treeData.routes.length > 0) {
+ treeData.routes.forEach((a: any) => {
+ treeLoop(a);
treeLoop(routes[0]);
export const layout = ({ initialState: { userData } }: { initialState: InitialStateType }): BasicLayoutProps => {
headerRender: false,
* @Date: 2022-01-12 15:26:43
- * @LastEditTime: 2022-08-01 10:57:12
+ * @LastEditTime: 2023-06-20 14:58:15
* @FilePath: /KC-MiddlePlatform/src/components/KCModal/index.tsx
@@ -2,158 +2,190 @@
* @Author: code4eat awesomedema@gmail.com
* @Date: 2022-06-29 11:05:04
- * @LastEditTime: 2022-07-14 15:37:31
+ * @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 } from 'antd';
-import React, { useEffect, useState } from 'react';
+import { Tabs, Checkbox, Button, message } from 'antd';
+import React, { Key, useEffect, useState } from 'react';
import './style.less';
+import { findNodesBySomes, getLeafNodes } from '@/utils';
const { TabPane } = Tabs;
export type NavSelecterItemType = {
- name: string;
- menuId: number | string;
- path: string;
- type: number;
- systemId: string;
-}
+ name: string;
+ menuId: number | string;
+ path: string;
+ type: number;
+ contentType: number;
+ systemId: string;
export type NavSelecterData = {
- child?: NavSelecterData[]
+ child?: NavSelecterData[];
export interface NavSelecter {
- onVisibleChange?: (t: boolean) => void;
- onChecked?: (t: NavSelecterItemType[]) => void;
- value?: NavSelecterItemType[];
- data?: NavSelecterData[];
+ onVisibleChange?: (t: boolean) => void;
+ onChecked?: (t: NavSelecterItemType[]) => void;
+ value?: Key[];
+ data?: NavSelecterData[];
+ title?: string;
+ type?: number; //1 默认 2 限制最多可选个数
const NavSelecter = (props: NavSelecter) => {
- const { onVisibleChange, data, value = [], onChecked } = props;
- const [checkedIds, set_checkedIds] = useState<(string | number)[]>([]);
- const [checkedItems, set_checkedItems] = useState<NavSelecterItemType[]>([]);
- 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]);
- } else {
- _checkedIds.push(tab.menuId);
- _checkedItems.push(tab);
- const onMaskClick = (e: React.MouseEvent) => {
- onVisibleChange && onVisibleChange(false);
+ const { onVisibleChange, data, value = [], onChecked, title, type = 1 } = props;
+ const [checkedIds, set_checkedIds] = useState<(string | number)[]>([]);
+ const [checkedItems, set_checkedItems] = useState<NavSelecterItemType[]>([]);
+ 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]);
+ if (type == 2 && checkedIds.length + 1 > 6) {
+ message.warn('快速入口最多展示6项');
+ _checkedIds.push(tab.menuId);
+ _checkedItems.push(tab);
- const onCommit = () => {
- onChecked && onChecked(checkedItems);
+ const onMaskClick = (e: React.MouseEvent) => {
+ onVisibleChange && onVisibleChange(false);
+ const onCommit = () => {
+ onChecked && onChecked(checkedItems);
+ const onReset = () => {
+ set_checkedItems([]);
+ set_checkedIds([]);
+ const checkAllHandle = (e: any) => {
+ let all: any[] = [];
+ if (e.target.checked) {
+ data?.forEach((item) => {
+ const _result = getLeafNodes({ child: item.child });
+ all = [...all, ..._result];
+ set_checkedItems([...all]);
+ set_checkedIds(all.map((a) => a.menuId));
- const onReset = () => {
- set_checkedItems([]);
- set_checkedIds([]);
+ useEffect(() => {
+ if (data) {
+ let result: any[] = [];
- useEffect(() => {
- set_checkedIds(value?.map(t => t.menuId));
- set_checkedItems(value);
- }, [value]);
- return (
- <div className="navSelecter" onClick={(e) => onMaskClick(e)}>
- <div className='container'>
- <div className='closeBtn' onClick={(e) => onMaskClick(e)}>
- <img src={require('./images/close.png')} />
- </div>
- <div className='content' onClick={(e) => e.stopPropagation()}>
- <div>
- <Tabs defaultActiveKey="1" >
- data?.map((val) => (
- <TabPane tab={val.name} 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) {
- <div className='tab' key={a.menuId}>
- <Checkbox onChange={() => onChange({
- name: a.name,
- menuId: a.menuId,
- path: a.path,
- type: a.type,
- systemId: a.systemId
- })} checked={checkedIds.includes(a.menuId)} ></Checkbox>
- <span style={{ marginLeft: 8 }}>{a.name}</span>
- )
- ))
- </TabPane>
+ for (let tree of data) {
+ const node = findNodesBySomes(tree, new Set(checkedIds), 'menuId');
+ if (node) {
+ result = result.concat([...node]);
+ set_checkedItems(result);
+ }, [checkedIds]);
+ set_checkedIds(value);
+ }, [value]);
+ return (
+ <div className="navSelecter" onClick={(e) => onMaskClick(e)}>
+ <div className="container">
+ <div className="selecterTitle">{title}</div>
+ <div className="closeBtn" onClick={(e) => onMaskClick(e)}>
+ <img src={require('./images/close.png')} />
+ </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) {
+ <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>
- </Tabs>
- <div className='footer' onClick={e => e.stopPropagation()}>
- <span className='count'>{`已选中${checkedIds.length}项`}</span>
- <div className='btnGroup'>
- <Button style={{ marginRight: 8 }} onClick={onReset}>重置</Button>
- <Button type="primary" onClick={onCommit}>确定</Button>
+ })}
+ ))}
+ </TabPane>
+ </Tabs>
</div>
+ <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项`}
+ </span>
+ <div className="btnGroup">
+ <Button className="resetBtn btn" style={{ marginRight: 8 }} onClick={onReset}>
+ 重置
+ </Button>
+ <Button className="confirmBtn btn" type="primary" onClick={onCommit}>
+ 确定
-export default NavSelecter;
+export default NavSelecter;
@@ -9,23 +9,40 @@
left: 0;
z-index: 999;
background-color: rgba(41, 44, 51, 0.5);
+ .kcmp-ant-tabs-tab {
+ padding-bottom: 6px !important;
+ padding-top:16px !important;
+ .kcmp-ant-tabs-top > .kcmp-ant-tabs-nav::before {
+ border-bottom: none !important;
.container {
position: relative;
- width: 70%;
- height: 60%;
+ width: 792px;
padding-top: 12px;
background: #FFFFFF;
- border-radius: 4px;
- border: 1px solid #CFD6E6;
+ border-radius: 8px;
+ .selecterTitle {
+ position: absolute;
+ top: 16px;
+ left: 16px;
+ height: 18px;
+ font-size: 16px;
+ font-weight: 500;
+ color: #17181A;
+ line-height: 18px;
.closeBtn {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
- right: 20px;
- top: 10px;
+ right:8px;
+ top: 8px;
width: 30px;
height: 30px;
cursor: pointer;
@@ -37,14 +54,13 @@
.content {
- padding: 24px;
- height: calc(100% - 56px);
- overflow-y: hidden;
+ padding: 16px;
.contentInner {
- height:368px;
- overflow-y: scroll;
+ min-height: 100px;
+ max-height: 440px;
+ overflow-y: scroll;
.row {
margin-bottom: 16px;
@@ -111,11 +127,33 @@
justify-content: space-between;
height: 56px;
- padding: 0 24px;
+ padding: 0 19px;
- border-radius: 0px 0px 4px 4px;
- border-top: 1px solid #CFD6E6;
+ border-radius: 0px 0px 8px 8px;
+ .btnGroup {
+ .btn {
+ width: 56px;
+ height: 24px;
+ font-size: 14px;
+ border-radius: 4px;
+ &>span {
+ position: relative;
+ top:-4px;
+ left:-2px;
+ &.resetBtn {
+ background: #FAFCFF;
+ border: 1px solid #DAE2F2;
+ &.confirm {
+ color: #FFFFFF;
+ background: #3377FF;
@@ -22,14 +22,23 @@
- .kcmp-ant-table-tbody>tr>td {
- border-bottom: 1px solid #DAE2F2;
- padding: 9px 8px !important;
- &:first-child {
- padding-left: 16px !important;
+ .kcmp-ant-table-tbody {
+ tr {
+ &>td {
+ border-bottom: 1px solid #DAE2F2;
+ padding: 9px 8px !important;
+ &:first-child {
+ padding-left: 16px !important;
+ .kcmp-ant-table-measure-row {
+ padding: 0 !important;
.kcmp-ant-table-tbody > tr.kcmp-ant-table-row:hover > td, .kcmp-ant-table-tbody > tr > td.kcmp-ant-table-cell-row-hover {
* @Date: 2021-11-16 09:12:37
- * @LastEditTime: 2023-03-24 16:34:14
+ * @LastEditTime: 2024-04-09 14:27:27
* @FilePath: /KC-MiddlePlatform/src/pages/index/components/topBar/index.tsx
@@ -11,17 +11,16 @@ import React, { useEffect, useState } from 'react';
-import { Tooltip } from 'antd';
+import { Input, Modal, Tooltip } from 'antd';
import { LogoutOutlined, SettingOutlined } from '@ant-design/icons';
-import logo from '../../../public/images/kc-logo.png';
-import platFormMenuIcon from '../../../public/images/platformMenu.png';
+// import logo from '../../../public/images/kc-logo.png';
import tabCloseIcon from '../../../public/images/tabCloseIcon.png';
-import { history, useModel } from 'umi';
+import { history, useLocation, useModel } from 'umi';
import { Divider } from 'antd';
-import { addFastEntry, getUserPlatformNav } from '@/service/menu';
-import { NavSelecterData } from '../NavSelecter';
+import { updateTokenReq } from '@/service/user';
+import { logoutHandle } from '@/global';
interface TopBarType {
onTabChange?: (data: TopBar.Tab[]) => void; //当tab切换时回调
@@ -30,65 +29,69 @@ interface TopBarType {
userPannelTabClick?: (tag: 'SETTING' | 'LOGOUT' | 'SETUSERINFO') => void;
onCloseTab?: (data: TopBar.Tab) => void;
onTabClick?: (data: TopBar.Tab) => void;
- userData?: { name: string;[key: string]: any };
+ userData?: { name: string; [key: string]: any };
navData: TopBar.PanelData[];
+ logo?: string;
+ topBarTitle?: string;
const TopBar: React.FC<TopBarType> = (props) => {
- const { onTabChange, userPannelTabClick, onCloseTab, onTabClick, userData, navData,currentTab } = 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[]>([]);
- const [onTabSystemTabs,set_onTabSystemTabs] = useState<TopBar.Tab[]>([]); //tab导航可以放下的数量,剩余通过下拉获取
+ const [onTabSystemTabs, set_onTabSystemTabs] = useState<TopBar.Tab[]>([]); //tab导航可以放下的数量,剩余通过下拉获取
+ const [onTabSystemTabs_hide, set_onTabSystemTabs_hide] = useState<TopBar.Tab[]>([]); //下拉掩藏的导航
const { initialState, setInitialState } = useModel('@@initialState');
+ const [tokenUpdateModalVisible, set_tokenUpdateModalVisible] = useState(false);
+ const location = useLocation();
+ const [showMoreTabPannel, set_showMoreTabPannel] = useState(false);
const localSavedTab = localStorage.getItem('currentSelectedTab');
const currentSelectedTabFromLocal = localSavedTab ? JSON.parse(localSavedTab) : {};
- const _systemTabClickHandle = (item: TopBar.Tab) => {
+ let password: undefined | string = undefined;
+ const _systemTabClickHandle = (item: TopBar.Tab) => {
//导航栏tab点击
// console.log('_systemTabClickHandle',item);
onTabClick && onTabClick(item);
localStorage.setItem('currentSelectedTab', JSON.stringify(item));
setCurrentSelectedTab(item);
const _systemListClickHandle = (data: TopBar.Tab, currentActivedBlockIndex: number, index: number, i: number) => {
//导航栏系统菜单列表点击回调
if (currentSelectedTab?.menuId == data.menuId) return;
- //临时保存衣打开过的菜单
+ //临时保存衣打开过的菜单
const t = localStorage.getItem('visitedTabs');
- if(t){
+ if (t) {
let visitedTabs = JSON.parse(t);
- let index = visitedTabs.findIndex((t:TopBar.Tab)=>t.menuId == data.menuId);
- if(index == -1){
+ let index = visitedTabs.findIndex((t: TopBar.Tab) => t.menuId == data.menuId);
+ if (index == -1) {
visitedTabs.push(data);
- localStorage.setItem('visitedTabs',JSON.stringify(visitedTabs));
+ localStorage.setItem('visitedTabs', JSON.stringify(visitedTabs));
- localStorage.setItem('visitedTabs',JSON.stringify([data]));
+ localStorage.setItem('visitedTabs', JSON.stringify([data]));
_systemTabClickHandle(data); //触发一次tab点击
- set_pageTitle(panelData[currentActivedBlockIndex].child[index].name)
+ set_pageTitle(panelData[currentActivedBlockIndex].child[index].name);
if (panelData[currentActivedBlockIndex].child[index].child) {
- // console.log([...panelData[currentActivedBlockIndex].child[index].child])
+ //console.log([...panelData[currentActivedBlockIndex].child[index].child])
setSystemTabs([...panelData[currentActivedBlockIndex].child[index].child]);
setIfOpenPannel(false);
@@ -104,7 +107,7 @@ const TopBar: React.FC<TopBarType> = (props) => {
let _systemTabs = [...systemTabs];
let delIndex = -1;
- const filtered = _systemTabs.filter((t, index) => {
+ const filtered: any[] = _systemTabs.filter((t, index) => {
if (t.menuId == item.menuId) {
delIndex = index;
@@ -123,68 +126,88 @@ const TopBar: React.FC<TopBarType> = (props) => {
const UserPannel = () => {
return (
- <div className='userPannel'>
- <div className='userPannelTab' onClick={() => _userPannelTabClick('SETTING')}>
+ <div className="userPannel">
+ <div className="userPannelTab" onClick={() => _userPannelTabClick('SETTING')}>
<SettingOutlined />
- 设置
+ <span>设置</span>
- <div className='userPannelTab' onClick={() => _userPannelTabClick('LOGOUT')}>
+ <div className="userPannelTab" onClick={() => _userPannelTabClick('LOGOUT')}>
<LogoutOutlined />
- 退出
+ <span>退出</span>
);
- const goChannelIndex = (menuData:any) => {
+ const goChannelIndex = (menuData: any) => {
- onTabClick&&onTabClick(menuData)
+ onTabClick && onTabClick(menuData);
const goToHome = () => {
- history.replace('/index');
- setSystemTabs([]); //清空tab导航
- onTabChange && onTabChange([]);
- setCurrentSelectedTab(undefined);
- set_pageTitle('欢迎进入医管平台');
- setIfOpenPannel(false);
- localStorage.removeItem('currentSelectedTab');
- localStorage.removeItem('selectedKeys');
- localStorage.removeItem('visitedTabs');
- localStorage.removeItem('openKeys');
- const goSystemIndex = (name:string)=>{
- if(panelData[currentActivedBlockIndex]){
- const result:TopBar.TypeBlock[] = panelData[currentActivedBlockIndex].child.filter(t=>(t.name == name));
- if(result.length>0){
- _systemTabClickHandle(Object.assign(result[0]))
- // history.push(result[0].path)
+ const go = () => {
+ history.replace('/index');
+ setSystemTabs([]); //清空tab导航
+ onTabChange && onTabChange([]);
+ setCurrentSelectedTab(undefined);
+ set_pageTitle(topBarTitle);
+ setIfOpenPannel(false);
+ console.log('goHome');
+ localStorage.removeItem('currentSelectedTab');
+ localStorage.removeItem('selectedKeys');
+ // localStorage.removeItem('visitedTabs');
+ localStorage.removeItem('openKeys');
+ const currentSelectedSubHop_json = localStorage.getItem('currentSelectedSubHop');
+ if (currentSelectedSubHop_json) {
+ const currentSelectedSubHop = JSON.parse(currentSelectedSubHop_json);
+ if (currentSelectedSubHop.loadType) {
+ go();
+ const goSystemIndex = (name: string) => {
+ if (panelData[currentActivedBlockIndex]) {
+ const result: TopBar.TypeBlock[] = panelData[currentActivedBlockIndex].child.filter((t) => t.name == name);
+ if (result.length > 0) {
+ _systemTabClickHandle(Object.assign(result[0]));
+ // history.push(result[0].path)
const openNav = () => {
setIfOpenPannel(!ifOpenPannel);
+ const moreItemClickHandle = (systemData: TopBar.Tab) => {
+ //点击更多应用时
+ _systemTabClickHandle(systemData);
+ const temp = onTabSystemTabs[onTabSystemTabs.length - 1];
+ const _onTabSystemTabs = [...onTabSystemTabs];
+ const b = _onTabSystemTabs.filter((a) => a.systemId != temp.systemId);
+ set_onTabSystemTabs([...b, systemData]);
+ set_onTabSystemTabs_hide([...onTabSystemTabs_hide.filter((a) => a.systemId != systemData.systemId), temp]);
const reSetNav = (_panelData: TopBar.PanelData[], cur: TopBar.Tab) => {
- if (!(_panelData.length > 0)) return
+ if (!(_panelData.length > 0)) return;
if (JSON.stringify(cur) != '{}') {
let blockIndex = 0;
let channelIndex = 0;
const _currentSelectedTabFromLocal = cur;
one: for (let index = 0; index < _panelData.length; index++) {
blockIndex = index;
if (_panelData[index] && _panelData[index].child) {
two: for (let i = 0; i < _panelData[index].child.length; i++) {
channelIndex = i;
@@ -194,8 +217,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); //设置体系标题
break one;
@@ -206,154 +229,285 @@ const TopBar: React.FC<TopBarType> = (props) => {
if (_panelData && _panelData.length > 0 && _panelData[blockIndex].child) {
- setSystemTabs(_panelData[blockIndex].child[channelIndex].child); //恢复体系列表
+ setSystemTabs(_panelData[blockIndex].child[channelIndex].child); //恢复体系列表
setCurrentSelectedTab(_currentSelectedTabFromLocal);
localStorage.setItem('currentSelectedTab', JSON.stringify(_currentSelectedTabFromLocal));
setInitialState((s) => ({ ...s, currentSelectedSys: _currentSelectedTabFromLocal }));
+ // console.log({_currentSelectedTabFromLocal,location});
+ const { pathname } = location;
+ if (pathname.indexOf(_currentSelectedTabFromLocal.path) == -1) {
+ history.push(_currentSelectedTabFromLocal.path);
//_systemTabClickHandle(_currentSelectedTabFromLocal); //恢复选中的tab
+ const [hideTimer, setHideTimer] = useState<null | any>(null);
+ const handleTabMoreMouseLeave = () => {
+ // 设置一个延时器,在一段时间后隐藏morePannel
+ const timer = setTimeout(() => {
+ set_showMoreTabPannel(false);
+ }, 300); // 例如延迟300毫秒
+ setHideTimer(timer);
+ const handleMorePannelMouseEnter = () => {
+ // 清除延时器,防止morePannel隐藏
+ if (hideTimer) {
+ clearTimeout(hideTimer);
+ setHideTimer(null);
+ const handleMorePannelMouseLeave = () => {
+ const updateToken = async () => {
+ const { account } = JSON.parse(localStorage.getItem('userInfo') as string);
+ const hospSign = localStorage.getItem('hospSign');
+ const data = {
+ account,
+ password: password,
+ hospSign,
+ const resp = await updateTokenReq(data);
+ password = undefined;
+ set_tokenUpdateModalVisible(false);
if (currentSelectedTabFromLocal) {
reSetNav(navData, currentSelectedTabFromLocal);
set_panelData(navData);
- }, [navData])
- useEffect(()=>{
- if(currentTab)reSetNav(panelData,currentTab);
- },[currentTab]);
- // console.log('systemTabs.length',systemTabs.length);
- if(systemTabs.length>6){
- const tabs = systemTabs.filter((a:any,index:number)=>{
- //暂时限制只展示最多5个
- if(index<=5){
- return a
- set_onTabSystemTabs(tabs);
- set_onTabSystemTabs(systemTabs);
- },[systemTabs]);
+ }, [navData]);
useEffect(() => {
+ if (currentTab) reSetNav(panelData, currentTab);
+ }, [currentTab]);
- //_systemTabClickHandle(currentSelectedTabFromLocal); //恢复选中的tab
+ }, [topBarTitle]);
- document.body.addEventListener('click', (e:any) => {
+ if (systemTabs.length > 5) {
+ //set_onTabSystemTabs(tabs);
+ let _onTabSystemTabs: any[] = [];
+ let _set_onTabSystemTabs_hide: any[] = [];
+ systemTabs.forEach((a, index) => {
+ if (index <= 4) {
+ _onTabSystemTabs.push(a);
+ if (a.systemId == currentSelectedTabFromLocal.systemId) {
+ const _temp = _onTabSystemTabs[_onTabSystemTabs.length - 1];
+ _onTabSystemTabs.pop();
+ _set_onTabSystemTabs_hide.push(_temp);
+ _set_onTabSystemTabs_hide.push(a);
+ set_onTabSystemTabs(_onTabSystemTabs);
+ set_onTabSystemTabs_hide(_set_onTabSystemTabs_hide);
+ set_onTabSystemTabs(systemTabs);
+ }, [systemTabs]);
+ //_systemTabClickHandle(currentSelectedTabFromLocal); //恢复选中的tab
- const classes = ['panel', 'left','typeBlockIcon', 'typeBlock', 'active', 'right', 'row', 'rowDetai', 'channelName', 'channelList', 'systemTab', 'channelIcon'];
+ 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',
+ ];
if (e.target) {
- if (classes.includes(e.target.className)) {
- return
+ let key = e.target.className ? e.target.className : '';
+ if (classes.includes(key) || (typeof key == 'string' && key.indexOf('typeBlockIcon') != -1)) {
+ // 事件监听器的函数定义
+ const handleStorageChange = (e: any) => {
+ if (e.key === 'tokenExpired') {
+ set_tokenUpdateModalVisible(true);
+ // 添加事件监听器
+ window.addEventListener('removeLocalItemEvent', handleStorageChange);
+ // 返回的函数用于在组件卸载时移除事件监听器
+ return () => {
+ window.removeEventListener('removeLocalItemEvent', handleStorageChange);
}, []);
- <div className='topBar' onClick={e => e.stopPropagation()}>
- <div className='logoWrap'>
- <img className='logo' src={logo} onClick={() => goToHome()} />
- <Divider type="vertical" style={{ background: 'white', height: 16, opacity: 0.29, position: 'relative', top: 1, marginLeft: 24, marginRight: 8 }} />
- <div className='menu' onClick={() => openNav()}>
+ <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 className="name">{userData?.name}</div>
+ <Input.Password onChange={(e) => (password = e.target.value)} className="input" />
+ <div className="updateBtn" onClick={() => updateToken()}>
+ 解锁
+ <a onClick={() => logoutHandle()}>退出登录</a>
+ </Modal>
+ <div className="logoWrap">
+ {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="" />
- <span className='systemTitle' onClick={()=>goSystemIndex(pageTitle)}>{pageTitle}</span>
+ <span className="systemTitle" onClick={() => goSystemIndex(pageTitle)}>
+ {pageTitle}
- <div className='userRelaInfoWrap'>
+ <div className="userRelaInfoWrap">
<>
{/**
* 已打开的tab
*/}
- <div className='tabWrap'>
- {onTabSystemTabs&&(onTabSystemTabs).map((item, index) => (
- <div key={index} className={currentSelectedTab?.menuId == item.menuId ? `tab on` : `tab`} onClick={() => _systemTabClickHandle(item)}>
- <div className='tabText'>{item.name} </div>
- <div className='closeIconWrap'>
- <img src={tabCloseIcon} onClick={(e) => closeTabHandle(item, e)} />
+ <div className="tabWrap">
+ {onTabSystemTabs &&
+ onTabSystemTabs.map((item, index) => (
+ <div key={index} className={currentSelectedTab?.menuId == item.menuId ? `tab on` : `tab`} onClick={() => _systemTabClickHandle(item)}>
+ <div className="tabText">{item.name} </div>
+ <div className="closeIconWrap">
+ <img src={tabCloseIcon} onClick={(e) => closeTabHandle(item, e)} />
- ))}
+ {systemTabs.length > 5 && (
+ <div className={showMoreTabPannel ? 'tabMore active' : 'tabMore'} onMouseEnter={() => set_showMoreTabPannel(true)} onMouseLeave={handleTabMoreMouseLeave}>
+ {showMoreTabPannel && (
+ <div className="morePannel" onMouseEnter={handleMorePannelMouseEnter} onMouseLeave={handleMorePannelMouseLeave}>
+ {onTabSystemTabs_hide.map((item, index) => {
+ <div key={index} className="moreItem" onClick={() => moreItemClickHandle(item)}>
+ {/* <Tooltip placement="right" title={item.name}> */}
+ <span>{item.name}</span>
+ {/* </Tooltip> */}
+ )}
</>
- {/* <div className='notification'>
- <img className='notificationIcon' src={require('../../../public/images/notificationIcon.png')} />
- </div> */}
- <Tooltip title={<UserPannel />} color="#fff" onVisibleChange={(visible) => setArrowRotate(visible)}>
- <div className='user'>
- <img className='avator' src={require('../../../public/images/Mask.png')} />
- <span className='name'>{userData?.name}</span>
- <img className={arrowRotate ? `arrow on` : `arrow`} src={require('../../../public/images/arrow_white.png')} />
+ <div className="notification">
+ <img className="notificationIcon" src={require('../../../public/images/notificationIcon.png')} />
+ <Tooltip className="topBarTooltip" placement="bottomRight" title={<UserPannel />} color="#fff" onOpenChange={(visible) => setArrowRotate(visible)}>
+ <div className="user">
+ <div className="avator">
+ <img src={require('../../../public/images/avatar.png')} />
+ <div className="info">
+ <span className="hospName">{localStorage.getItem('hospAbbreviation')}</span>
+ <span className="name">{userData?.name}</span>
+ {/* <img className={arrowRotate ? `arrow on` : `arrow`} src={require('../../../public/images/arrow_white.png')} /> */}
</Tooltip>
- ifOpenPannel && (
- <div className='panel' onClick={e => e.stopPropagation()}>
- <div className='left'>
- panelData.map((item, index) => {
- <div className={currentActivedBlockIndex == index ? `typeBlock active` : `typeBlock`} key={index} onClick={() => set_currentActivedBlockIndex(index)}>
- {/* <img className='typeBlockIcon' src={item?.icon} alt="" /> */}
- <img className='typeBlockIcon' src={require('../../../public/images/blueBook.png')} alt="" />
- <span>{item.name}</span>
- <div className='right'>
- panelData.length > 0 && panelData[currentActivedBlockIndex] && panelData[currentActivedBlockIndex].child && panelData[currentActivedBlockIndex].child.map((item, index: number) => {
- <div className='row' key={index}>
- <img className='channelIcon' src={require('../../../public/images/zhilianganquan.png')} alt="" />
- <div className='rowDetail'>
- <div className='channelName' onClick={() => goChannelIndex(item)}>{item.name}</div>
- <div className='channelList'>
- item.child && item.child.length > 0 && item.child.map((val, i: number) => {
- <div className={currentSelectedTab?.menuId == val.menuId ? 'systemTab on' : 'systemTab'} key={i} onClick={() => _systemListClickHandle(val, currentActivedBlockIndex, index, i)}>{val.name}</div>
+ {ifOpenPannel && (
+ <div className="panel" onClick={(e) => e.stopPropagation()}>
+ <div className="left">
+ {panelData.map((item, index) => {
+ <div className={currentActivedBlockIndex == index ? `typeBlock active` : `typeBlock`} key={index} onClick={() => set_currentActivedBlockIndex(index)}>
+ {/* <img className='typeBlockIcon' src={item?.icon} alt="" /> */}
+ <div className={` typeBlockIcon typeBlockIcon${item.icon}`}></div>
+ <span className="typeBlockName">{item.name}</span>
+ <div className="right">
+ <div className="panelCloseBtn" onClick={() => setIfOpenPannel(false)}></div>
+ {panelData.length > 0 &&
+ panelData[currentActivedBlockIndex] &&
+ panelData[currentActivedBlockIndex].child &&
+ panelData[currentActivedBlockIndex].child.map((item, index: number) => {
+ <div className="row" key={index}>
+ <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 className="channelList">
+ {item.child &&
+ item.child.length > 0 &&
+ item.child.map((val, i: number) => {
+ <div
+ className={currentSelectedTab?.menuId == val.menuId ? 'systemTab on' : 'systemTab'}
+ key={i}
+ onClick={() => _systemListClickHandle(val, currentActivedBlockIndex, index, i)}
+ >
+ {val.name}
@@ -1,3 +1,89 @@
+.kcmp-ant-tooltip {
+ .kcmp-ant-tooltip-content {
+ right: 8px;
+}
+.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;
+ background-repeat: no-repeat !important;
+ background-position: right top !important;
+ .content {
+ height: 300px;
+ .title {
+ color: #17181a;
+ margin-bottom: 14px;
+ .form {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ .avatar {
+ width: 64px;
+ height: 64px;
+ margin-bottom: 8px;
+ .avatarImg {
+ width: 100%;
+ height: 100%;
+ .suoding {
+ bottom: 0;
+ right: 0;
+ width: 24px;
+ .name {
+ font-weight: 400;
+ font-size: 20px;
+ height: 20px;
+ line-height: 20px;
+ margin-bottom: 24px;
+ .input {
+ width: 240px;
+ height: 32px;
+ background: #ffffff;
+ .updateBtn {
+ cursor: pointer;
+ line-height: 32px;
+ background: #3377ff;
+ text-align: center;
+ color: #ffffff;
+ margin-bottom: 16px;
.userPannel {
width: 100px;
background-color: white;
@@ -5,18 +91,25 @@
.userPannelTab {
flex-direction: row;
- justify-content: space-evenly;
+ justify-content: flex-start;
font-size: 14px;
font-family: SourceHanSansCN-Normal, SourceHanSansCN;
font-weight: 400;
- color: rgb(131, 127, 127);
- border-bottom: 1px solid #eee;
+ padding-left: 12px;
+ border-radius: 2px;
+ & > span {
+ &:last-child {
+ margin-left: 8px;
&:hover {
- background-color: #eee;
+ background-color: #f5f7fa;
&:last-child {
@@ -25,16 +118,32 @@
+ padding-top: 0 !important;
+ .kcmp-ant-tooltip-arrow {
+ display: none;
+ .kcmp-ant-tooltip-inner {
.topBar {
+ justify-content: space-between;
width: 100%;
+ min-width: 1280px;
height: 48px;
padding-left: 16px;
- background: #3071f2;
* {
line-height: normal;
@@ -44,15 +153,22 @@
- width: 350px;
+ width: 400px;
.logo {
- width: 120px;
- height: 24px;
+ // width: 120px;
+ height: 40px;
.systemTitle {
+ font-family: SourceHanSansCN-Medium, SourceHanSansCN;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
.menu {
@@ -67,46 +183,46 @@
transition: all 0.3s ease-in;
background: rgba(254, 255, 255, 0);
- &>img {
+ & > img {
width: 16px;
height: 16px;
+ &.active {
+ background: rgba(254, 255, 255, 0.1);
background: rgba(254, 255, 255, 0.1);
- &>span {
font-family: SourceHanSansCN-Medium, SourceHanSansCN;
font-weight: 500;
- color: #FFFFFF;
.userRelaInfoWrap {
width: 55%;
justify-content: flex-end;
- position: fixed;
- right: 0;
- padding-right: 16px;
.tabWrap {
width: 60%;
- justify-content:flex-end;
+ justify-content: flex-end;
- margin-right: 24px;
+ margin-right: 8px;
.tab {
- max-width:180px;
+ max-width: 180px;
height: 32px;
line-height: 32px;
text-align: center;
@@ -116,7 +232,7 @@
padding: 0 2%;
border-radius: 4px;
opacity: 0.8;
- margin-right:1%;
+ margin-right: 1%;
box-sizing: border-box;
@@ -149,7 +265,7 @@
&.on {
opacity: 1;
- background: #0b54e6;
+ background: #1963fa;
@@ -158,18 +274,92 @@
+ .tabMore {
+ z-index: 999;
+ width: 32px;
+ .morePannel {
+ top: 40px;
+ width: 130px;
+ background: #f5f7fa;
+ box-shadow: 0px 10px 20px 0px rgba(31, 71, 153, 0.2);
+ opacity: 0.98;
+ padding: 8px;
+ .moreItem {
+ span {
+ font-size: 12px;
+ font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+ &:hover {
+ background: #3376fe;
+ &::after {
+ // top: 3px;
+ // left: 6px;
+ display: inline-block;
+ content: '';
+ background: url('../../../public/images/threePoint_white_more.png');
+ background-size: 24px 24px;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background: rgba(249, 248, 248, 0.1);
.notification {
- width: 18px;
- height: 18px;
- margin-right: 16px;
.notificationIcon {
- width: 100%;
+ width: 16px;
+ height: 16px;
@@ -179,19 +369,58 @@
+ //margin-left: 16px;
+ height: 48px;
+ padding-right: 16px;
+ padding-left: 8px;
+ background: linear-gradient(90deg, #66a6ff 0%, #3366ff 100%);
+ border-radius: 24px 0px 0px 24px;
.avator {
- width: 26px;
- height: 26px;
margin-right: 8px;
+ border-radius: 50%;
+ border: 1px solid #ffffff;
+ img {
+ width: 101%;
+ height: 101%;
- .name {
- font-size: 14px;
- font-family: SourceHanSansCN-Normal, SourceHanSansCN;
- font-weight: 400;
- color: #ffffff;
- margin-right: 10px;
+ .info {
+ align-items: flex-start;
+ .hospName {
+ height: 13px;
+ line-height: 13px;
+ margin-bottom: 7px;
+ opacity: 0.9;
.arrow {
@@ -209,17 +438,17 @@
.panel {
- align-items:stretch;
+ align-items: stretch;
top: 48px;
- left: 165px;
+ left: 170px;
min-height: 140px;
- width: 80%;
- border-radius: 0px 0px 0px 8px;
- background: #F5F7FA;
+ width: 980px;
box-shadow: 0px 10px 20px 0px rgba(31, 71, 153, 0.2);
border-radius: 0px 0px 8px 8px;
opacity: 0.98;
.left {
width: 140px;
@@ -238,59 +467,254 @@
margin: 0 auto;
- width: 32px;
- height: 32px;
+ .typeBlockIcon {
+ width: 40px;
margin-bottom: 8px;
font-size: 12px;
color: #515866;
+ .typeBlockIcon1 {
+ background: url('../../../public/images/jingyiyiliao_gray.png');
+ background-size: contain;
+ .typeBlockIcon2 {
+ background: url('../../../public/images/HBI_gray.png');
+ .typeBlockIcon3 {
+ background: url('../../../public/images/zhongtaiguanli_gray.png');
+ .typeBlockIcon4 {
+ background: url('../../../public/images/guanlizhongxin_gray.png');
+ .typeBlockIcon5 {
+ background: url('../../../public/images/feiyi_gray.png');
&.active {
+ background: #f2f7ff;
+ background: url('../../../public/images/jingyiyiliao.png');
+ background: url('../../../public/images/HBI.png');
+ background: url('../../../public/images/zhongtaiguanli.png');
- color: #3376FE;
+ background: url('../../../public/images/guanlizhongxin.png');
+ background: url('../../../public/images/feiyi.png');
+ color: #3376fe;
+ // background: #F5F7FA;
+ // &:nth-child(2) {
+ // .typeBlockIcon2 {
+ // background: url('../../../public/images/HBI_gray.png');
+ // background-size: contain;
+ // &.active {
+ // background: #F2F7FF;
+ // background: url('../../../public/images/HBI.png');
+ // &>span {
+ // color: #3376FE;
+ // &:hover {
+ // &:nth-child(3) {
+ // .typeBlockIcon3 {
+ // background: url('../../../public/images/zhongtaiguanli_gray.png');
+ // background: url('../../../public/images/zhongtaiguanli.png');
+ // &:nth-child(4) {
+ // .typeBlockIcon4 {
+ // background: url('../../../public/images/guanlizhongxin_gray.png');
+ // background: url('../../../public/images/guanlizhongxin.png');
.right {
width: calc(100% - 140px);
height: 100%;
+ max-height: 572px;
padding: 2% 2.5%;
+ overflow: scroll;
+ .panelCloseBtn {
+ width: 12px;
+ height: 12px;
+ right: 16px;
+ background: url('../../../public/images/close.png');
justify-content: flex-start;
align-items: flex-start;
.channelIcon {
width: 24px;
height: 24px;
+ margin-right: 17px;
.rowDetail {
.channelName {
display: inline-block;
- color: #7A8599;
+ color: #7a8599;
@@ -303,15 +727,15 @@
.systemTab {
- width: 24%;
+ width: 180px;
- background: #FFFFFF;
- color: #17181A;
padding-left: 8px;
margin-right: 1%;
@@ -323,16 +747,20 @@
color: white;
- background: linear-gradient(90deg, #3376FE 0%, #66A6FF 100%);
+ background: linear-gradient(90deg, #3376fe 0%, #66a6ff 100%);
+ margin-bottom: 0;
* @Date: 2022-01-10 13:56:19
- * @LastEditTime: 2022-07-11 18:12:01
+ * @LastEditTime: 2023-09-07 17:37:27
* @FilePath: /KC-MiddlePlatform/src/components/topBar/typings.d.ts
@@ -16,7 +16,7 @@ declare namespace TopBar {
url?: string;
path: string;
type:number;
- contentType:string;
+ contentType:number;
isSetupMenu?:number;
* @Date: 2022-01-14 16:09:09
- * @LastEditTime: 2022-07-26 09:45:51
+ * @LastEditTime: 2023-12-26 19:48:10
* @FilePath: /KC-MiddlePlatform/src/constant.ts
@@ -56,3 +56,5 @@ export const Platforms = [
logo: pfmIcon,
];
+export const KcimCenterSysId = '1547394914533380096';
@@ -3,6 +3,11 @@
padding: 0;
+body {
+ margin: 0;
+ zoom: unset !important;
input {
outline: none !important;
@@ -23,7 +28,7 @@ input {
.kcmp-ant-layout {
.kcmp-ant-pro-table-search {
@@ -35,26 +40,24 @@ input {
/**
input
**/
.kcmp-ant-input-affix-wrapper {
padding: 0px 8px;
- border: 1px solid #CFD7E6;
+ border: 1px solid #cfd7e6;
- &>input {
+ & > input {
&::placeholder {
- color: #99A6BF;
+ color: #99a6bf;
Form
@@ -74,26 +77,23 @@ input {
.kcmp-ant-form-item-control-input {
.kcmp-ant-form-item-control-input-content {
textarea {
padding: 4px 8px;
border-radius: 4px !important;
.kcmp-ant-input {
//padding-left: 8px;
input-number
@@ -101,39 +101,37 @@ input {
.kcmp-ant-input-number {
.kcmp-ant-input-number-handler-wrap {
.kcmp-ant-input-number-handler {
- border-left: 1px solid #CFD7E6;
+ border-left: 1px solid #cfd7e6;
.kcmp-ant-input-number-handler-down {
- border-top: 1px solid #CFD7E6;
+ border-top: 1px solid #cfd7e6;
.kcmp-ant-input-number-handler-up-inner,
.kcmp-ant-input-number-handler-down-inner {
.kcmp-ant-input-number-input-wrap {
.kcmp-ant-input-number-input {
height: 22px;
line-height: 24px;
padding: 0 8px;
-.kcmp-ant-table-thead>tr>th {
+.kcmp-ant-table-thead > tr > th {
border-bottom: none;
&::before {
@@ -141,7 +139,6 @@ input {
Select
@@ -150,7 +147,7 @@ input {
height: 24px !important;
padding: 0 8px !important;
- border: 1px solid #CFD7E6 !important;
+ border: 1px solid #cfd7e6 !important;
.kcmp-ant-select-selection-item {
@@ -165,25 +162,25 @@ input {
.kcmp-ant-select-arrow {
- color: #CFD7E6;
+ color: #cfd7e6;
&.kcmp-ant-select-disabled {
.kcmp-ant-select-selector {
- border: 1px solid #DADEE6 !important;
+ border: 1px solid #dadee6 !important;
.kcmp-ant-select-selection-placeholder {
@@ -197,28 +194,25 @@ input {
.kcmp-ant-transfer {
.kcmp-ant-transfer-list {
- border: 1px solid #DAE2F2;
+ border: 1px solid #dae2f2;
.kcmp-ant-transfer-list-header {
+ border-bottom: 1px solid #dae2f2;
.kcmp-ant-modal {
padding-bottom: 0;
border-radius: 8px;
overflow: hidden;
.kcmp-ant-modal-content {
.kcmp-ant-modal-close-x {
.kcmp-ant-modal-header {
@@ -226,8 +220,9 @@ input {
font-size: 16px;
+ padding-bottom: 0;
.kcmp-ant-modal-body {
@@ -270,44 +265,47 @@ input {
-div::-webkit-scrollbar {
- width: 2px;
- height: 2px;
+*::-webkit-scrollbar {
+ width: 4px !important;
+ height: 10px !important;
/**/
-div::-webkit-scrollbar-track {
+*::-webkit-scrollbar-track {
background: transparent;
border-radius: 2px;
-div::-webkit-scrollbar-thumb {
- background: #bfbfbf;
+*::-webkit-scrollbar-thumb {
+ background: rgba(228, 231, 235, 0.7) !important;
border-radius: 10px;
-div::-webkit-scrollbar-thumb:hover {
+*::-webkit-scrollbar-thumb:hover {
width: 4px;
height: 4px;
- background: rgb(136, 135, 135);
+ background: rgba(228, 231, 235, 0.7);
-div::-webkit-scrollbar-corner {
+*::-webkit-scrollbar-corner {
+//----------- Menu左侧菜单
+.kcmp-ant-layout-sider {
+ &.kcmp-ant-layout-sider-collapsed {
+ width: 60px !important;
+ flex: 0 0 60px !important;
+ max-width: 60px !important;
+ min-width: 60px !important;
//--------------------
//Transfer
.TableTransfer {
.kcmp-ant-transfer-operation {
@@ -320,13 +318,13 @@ div::-webkit-scrollbar-corner {
height: 40px !important;
// background: #FAFCFF;
.anticon {
.kcmp-ant-transfer-list-header-selected {
@@ -340,7 +338,7 @@ div::-webkit-scrollbar-corner {
.kcmp-ant-input-prefix {
.anticon-search {
@@ -350,13 +348,12 @@ div::-webkit-scrollbar-corner {
.kcmp-ant-table-container {
.kcmp-ant-table-content {
.kcmp-ant-table-thead {
- &>tr>th {
+ & > tr > th {
- background: #EEF3FA;
+ background: #eef3fa;
padding: 4px 8px !important;
@@ -364,47 +361,62 @@ div::-webkit-scrollbar-corner {
//checkbox
.kcmp-ant-checkbox {
.kcmp-ant-checkbox-inner {
-.kcmp-ant-checkbox+span {
+.kcmp-ant-checkbox + span {
padding-left: 4px;
padding-right: 4px;
//drawer
.kcmp-ant-drawer-body {
padding: 16px;
//Picker
.kcmp-ant-picker {
padding: 0px 11px !important;
.kcmp-ant-picker-input {
- input {
- &::placeholder {
+ input {
+ &::placeholder {
.kcmp-ant-picker-suffix {
+/**
+ Layout
+**/
+.kcmp-ant-pro-sider {
+ .bms-ant-layout-sider-children {
+ padding-inline: 8px;
+ .kcmp-ant-pro-sider-collapsed-button {
+ border-top: 1px solid transparent;
+.kcmp-ant-pro-sider-collapsed-button .anticon {
+ font-size: 24px !important;
+.kcmp-ant-layout-header {
+ z-index: 200 !important;
* @Date: 2021-12-21 11:05:37
- * @LastEditTime: 2023-03-23 16:49:49
+ * @LastEditTime: 2024-03-28 18:04:34
* @FilePath: /KC-MiddlePlatform/src/global.tsx
@@ -18,10 +18,12 @@ const loginPath = '/login';
export const logoutHandle = async () => {
// await logout();
+ console.log('logoutHandle');
localStorage.removeItem('userData');
localStorage.removeItem('initialState');
+ // localStorage.removeItem('currentSelectedTab');
//localStorage.removeItem('isChildShowMenu');
localStorage.removeItem('selectedKeys');
localStorage.removeItem('openKeys');
// localStorage.removeItem('visitedTabs');
* @Date: 2021-11-09 13:56:33
- * @LastEditTime: 2023-02-27 10:38:07
+ * @LastEditTime: 2024-01-18 15:45:55
* @FilePath: /KC-MiddlePlatform/src/layouts/index.tsx
@@ -12,42 +12,62 @@ import ProLayout from '@ant-design/pro-layout';
import TopBar from '@/components/topBar';
import { Key, useEffect, useState } from 'react';
-import { getPlatformMenu, getSpecifyMenuDetail, getUserPlatformNav } from '@/service/menu';
-import { NavSelecterData } from '@/components/NavSelecter';
-const TopHoc = ({ currentSelectedSys, openedSysLists, navData,set_emptyPageContent }: {set_emptyPageContent:any; currentSelectedSys: TopBar.Tab | undefined, openedSysLists: TopBar.Tab[], navData: TopBar.PanelData[] }) => {
+import { getSpecifyMenuDetail, getUserPlatformNav } from '@/service/menu';
+import { getAppAccess, getSysParamsByCode } from '@/service';
+import { Modal } from 'antd';
+import { KcimCenterSysId } from '@/constant';
+const TopHoc = ({
+ currentSelectedSys,
+ openedSysLists,
+ navData,
+ set_emptyPageContent,
+ logo,
+ topBarTitle,
+}: {
+ set_emptyPageContent: any;
+ currentSelectedSys: TopBar.Tab | undefined;
+ openedSysLists: TopBar.Tab[];
+ navData: TopBar.PanelData[];
+ logo: string;
+ topBarTitle: string;
+}) => {
- const onTabChangeHandle = async (data: TopBar.Tab[]) => {
+ const onTabChangeHandle = async (data: TopBar.Tab[]) => {};
const onTabClickHandle = async (data: TopBar.Tab) => {
- if(JSON.stringify(data) != '{}'){
- await setInitialState((s) => ({ ...s, currentSelectedSys: data }));
- if(data.contentType == '4'){
+ const { systemId = '', menuId = '' } = data;
+ const resp = await getAppAccess(systemId.length > 0 ? systemId : menuId);
+ if (!resp) {
+ if (JSON.stringify(data) != '{}') {
+ await setInitialState((s) => ({ ...s, currentSelectedSys: data }));
+ if (data.contentType == 4) {
//空白页面
- if(data.isSetupMenu){
+ if (data.isSetupMenu) {
//体系菜单掩藏子应用的menu
- localStorage.setItem('isChildShowMenu','false');
+ localStorage.setItem('isChildShowMenu', 'false');
history.push(`${data.path}?isEmpty=true&menuId=${data.menuId}`);
- //体系菜单掩藏子应用的menu
- localStorage.setItem('isChildShowMenu','true');
+ //体系菜单掩藏子应用的menu
+ localStorage.setItem('isChildShowMenu', 'true');
+ history.push(data.path);
- history.push(data.path);
+ Modal.error({
+ title: '当前系统未注册,请联系管理员处理!',
@@ -60,29 +80,29 @@ const TopHoc = ({ currentSelectedSys, openedSysLists, navData,set_emptyPageConte
if (tag == 'SETTING') {
if (initialState) {
- setInitialState((s) => ({
- ...s,
- currentSelectedSys: {
- menuId: -1,
- name: '个人中心',
- icon: '',
- url: '',
- systemId: '-1',
- type:1,
- contentType:'0',
- path: '/personalCenter',
+ // setInitialState((s) => ({
+ // ...s,
+ // currentSelectedSys: {
+ // menuId: -1,
+ // name: '个人中心',
+ // icon: '',
+ // url: '',
+ // systemId: '-1',
+ // type:1,
+ // contentType:'0',
+ // path: '/personalCenter',
+ history.push('/personalCenter');
<TopBar
navData={navData}
+ logo={logo}
+ topBarTitle={topBarTitle}
userData={initialState?.userData}
openedTabs={openedSysLists}
onTabChange={onTabChangeHandle}
@@ -90,7 +110,6 @@ const TopHoc = ({ currentSelectedSys, openedSysLists, navData,set_emptyPageConte
currentTab={currentSelectedSys}
userPannelTabClick={userPannelTabClickhandle}
/>
@@ -98,46 +117,79 @@ export default function Layout({ children, location, route, history, match }: IR
const [navData, set_navData] = useState<TopBar.PanelData[]>([]);
const [emptyPageContent, set_emptyPageContent] = useState('');
- const [isEmpty,set_isEmpty] = useState(false);
+ const [isEmpty, set_isEmpty] = useState(false);
+ const [topBarLogoUrl, set_topBarLogoUrl] = useState<string>('');
+ const [topBarTitle, set_topBarTitle] = useState('');
+ const [iframeUrl, set_iframeUrl] = useState<string | undefined>(undefined);
const getNavData = async () => {
const nav = await getUserPlatformNav();
if (nav) {
- set_navData(nav);
+ set_navData(nav as any);
+ const getAllParamsHanle = async () => {
+ const resp = await getSysParamsByCode(KcimCenterSysId);
+ resp.forEach((item: any) => {
+ if (item.code == '1739122834787143680') {
+ set_topBarLogoUrl(item.value);
+ if (item.code == '1739123252502073344') {
+ set_topBarTitle(item.value);
- const getEmptyPageContent = async (menuId:Key) => {
+ const getEmptyPageContent = async (menuId: Key) => {
const menuItem = await getSpecifyMenuDetail(menuId);
set_emptyPageContent(menuItem.description);
if (location.pathname != '/login') {
getNavData();
- if(location.query.isEmpty == 'true'&&location.query.menuId){
- getEmptyPageContent(location.query.menuId as string)
+ if (location.pathname == '/index') {
+ //localStorage.removeItem('currentSelectedTab');
+ //localStorage.removeItem('isChildShowMenu');
+ if (location.query.isEmpty == 'true' && location.query.menuId) {
+ getEmptyPageContent(location.query.menuId as string);
- }, [])
+ }, []);
- if(location.pathname != '/platform'){
+ if (location.pathname != '/platform') {
//排除已有系统的空白页面
set_isEmpty(location.query.isEmpty == 'true');
if (location.pathname == '/login') {
return <div>{children}</div>;
+ getAllParamsHanle();
+ // if (initialState?.currentSelectedSys) {
+ // const { type, url, contentType } = initialState.currentSelectedSys;
+ // if (type == 1 && contentType == 6) {
+ // const userData = localStorage.getItem('userData');
+ // const { token } = JSON.parse(userData as string);
+ // return (
+ // <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={addTokenToUrl(url as string, token)} onLoad={() => adjustIframe()} ></iframe>
+ // )
<ProLayout
layout="top"
@@ -153,17 +205,16 @@ export default function Layout({ children, location, route, history, match }: IR
>
{dom}
</a>
}}
menu={{
request: async () => {
return [
- name: '欢迎进入医管平台'
- ]
+ name: topBarTitle,
pageTitleRender={false}
@@ -171,6 +222,8 @@ export default function Layout({ children, location, route, history, match }: IR
initialState && (
<TopHoc
+ logo={topBarLogoUrl as string}
set_emptyPageContent={set_emptyPageContent}
currentSelectedSys={initialState.currentSelectedSys}
openedSysLists={initialState.openedSysLists ? initialState.openedSysLists : []}
@@ -178,14 +231,12 @@ export default function Layout({ children, location, route, history, match }: IR
)
- isEmpty&& (
- <div style={{ textAlign: 'center', paddingTop: 100,height:'93vh' }}>
- <h1>{emptyPageContent}</h1>
- {!isEmpty&&(<div style={{ height: `calc(100vh - 48px)`, overflowY: 'scroll' }}>{children}</div>)}
+ {isEmpty && (
+ <div style={{ textAlign: 'center', paddingTop: 100, height: '93vh' }}>
+ <h1>{emptyPageContent}</h1>
+ {!isEmpty && <div style={{ height: `calc(100vh - 48px)`, overflowY: 'scroll', minWidth: 1280 }}>{children}</div>}
</ProLayout>
@@ -2,190 +2,191 @@
* @Date: 2022-05-27 14:17:59
- * @LastEditTime: 2023-03-07 15:56:31
+ * @LastEditTime: 2024-01-16 16:50:20
* @FilePath: /KC-MiddlePlatform/src/pages/index/components/FastEntry/index.tsx
//快速入口模块
import { history, useModel } from 'umi';
import { useEffect, useState } from 'react';
-import { Empty } from 'antd';
+import { Empty, Modal } from 'antd';
import NavSelecter, { NavSelecterData, NavSelecterItemType } from '@/components/NavSelecter';
import { addFastEntry, AddFastEntryDataType, getUserPlatformNav } from '@/service/menu';
+import { getAppAccess } from '@/service';
+import { createFromIconfontCN } from '@ant-design/icons';
export type FastEntryTabType = {
- systemId:string;
- type:number;
- menuId:number|string;
export interface FastEntryType {
- data: FastEntryTabType[];
+ data: FastEntryTabType[];
-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[]>([]);
- const tabClickHandle = async (tab: FastEntryTabType) => {
- await setInitialState((s) => ({ ...s, currentSelectedSys:tab as any,currentTab:tab}));
- history.push(tab.path)
+const IconFont = createFromIconfontCN({
+ scriptUrl: '',
+});
- const getNavData =async () => {
- const navData = await getUserPlatformNav();
- set_navSelecterData(navData)
+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[]>([]);
+ const tabClickHandle = async (tab: FastEntryTabType) => {
+ const { systemId = '', menuId = '', contentType, type } = tab;
+ await setInitialState((s) => ({ ...s, currentSelectedSys: tab as any, currentTab: tab }));
+ if (type == 1 && contentType == 6) {
+ //体系或第三方iframe
+ history.push('/platform');
+ history.push(tab.path);
- const onCheckedHandle = async (data:NavSelecterItemType[])=>{
- const resp = await addFastEntry(data as AddFastEntryDataType[]);
- if(resp){
- set_tabs(data);
+ const getNavData = async () => {
+ const navData = await getUserPlatformNav();
+ set_navSelecterData(navData);
- const addHandle = ()=>{
- getNavData();
- set_open(true);
+ const onCheckedHandle = async (data: NavSelecterItemType[]) => {
+ const resp = await addFastEntry(data as AddFastEntryDataType[]);
+ set_tabs(data);
- const { data } = props;
- }, [props]);
- // set_navSelecterData([
- // name:'精益医疗管理',
- // key:0,
- // children:[
- // name:'质量安全管理',
- // key:1,
- // name:'质量管理及十大安全目标',
- // key:2
- // key:3
- // key:4
- // key:20
- // key:21
- // }
- // ]
- // name:'质量安全管理2',
- // key:30,
- // key:31
- // key:32
- // key:33
- // key:34
- // key:35
- // name:'HBI',
- // key:5,
- // key:6,
- // key:7
- // ])
- },[])
- <div className='fastEntry'>
- <div className='topTitle'>
- <span className='name'>快速入口</span>
- <span className='addBtn' onClick={()=>addHandle()}>添加</span>
- open&&(
- <NavSelecter data={navSelecterData} onVisibleChange={(bool)=>set_open(bool)} value={tabs} onChecked={onCheckedHandle} />
- <div className='wrap'>
- tabs.map((item, index) => {
- <div className='tab' onClick={() => tabClickHandle(item)} key={index}>{item.name}</div>
- tabs.length == 0 && (
- <div className='empty'>
- <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
+ const addHandle = () => {
+ getNavData();
+ set_open(true);
+ const { data } = props;
+ }, [props]);
+ // set_navSelecterData([
+ // name:'精益医疗管理',
+ // key:0,
+ // children:[
+ // name:'质量安全管理',
+ // key:1,
+ // name:'质量管理及十大安全目标',
+ // key:2
+ // key:3
+ // key:4
+ // key:20
+ // key:21
+ // ]
+ // name:'质量安全管理2',
+ // key:30,
+ // key:31
+ // key:32
+ // key:33
+ // key:34
+ // key:35
+ // name:'HBI',
+ // key:5,
+ // key:6,
+ // key:7
+ // ])
+ <div className="fastEntry">
+ <div className="topTitle">
+ <span className="name">快速入口</span>
+ <span className="addBtn" onClick={() => addHandle()}>
+ 管理
+ {open && <NavSelecter type={2} title="选择应用" data={navSelecterData} onVisibleChange={(bool) => set_open(bool)} value={tabs.map((a) => a.menuId)} onChecked={onCheckedHandle} />}
+ <div className="wrap">
+ {tabs.slice(0, 6).map((item, index) => {
+ <div className="tab" onClick={() => tabClickHandle(item)} key={index}>
+ <IconFont type="icontubiao1" style={{ marginRight: 8 }} />
+ {tabs.length == 0 && (
+ <div className="empty">
+ {/* <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> */}
+ 添加系统快速入口,方便再次进入
@@ -1,9 +1,8 @@
.fastEntry {
flex-grow: 1;
- min-height: 153px;
+ height: 176px;
.topTitle {
@@ -11,20 +10,20 @@
padding: 0 16px;
- border-bottom: 1px solid #E6EAF2;
+ // border-bottom: 1px solid #E6EAF2;
.name {
.addBtn {
@@ -33,6 +32,7 @@
+ padding-top: 0;
flex-wrap: wrap;
.empty {
@@ -40,11 +40,13 @@
+ margin-top: 45px;
- width: 19.2%;
+ width: 48.7%;
+ margin-right: 2.5%;
text-align: left;
@@ -52,19 +54,31 @@
color: #525866;
- padding-left: 1%;
+ padding-left: 2%;
- &:nth-child(5n){
- margin-right: 0;
+ &:nth-child(2n) {
+ margin-right: 0;
+ // &::before {
+ // position: relative;
+ // top:3px;
+ // display: inline-block;
+ // content: '';
+ // width: 16px;
+ // height: 16px;
+ // margin-right: 8px;
+ // background: url('../../../../../public/images/icon-box.png');
@@ -2,75 +2,76 @@
* @Date: 2022-05-30 09:50:41
- * @LastEditTime: 2023-03-07 16:00:57
+ * @LastEditTime: 2023-11-10 17:20:09
* @FilePath: /KC-MiddlePlatform/src/pages/index/components/RecentlyVisited/index.tsx
//最近访问模块
-import {history, useModel} from 'umi';
+import { history, useModel } from 'umi';
import { NavSelecterItemType } from '@/components/NavSelecter';
export type RecentlyVisitedItemsType = {
- name:string;
- path:string;
- menuId:string;
+ menuId: string;
export interface RecentlyVisitedPropsType {
- data:RecentlyVisitedItemsType[]
+ data: RecentlyVisitedItemsType[];
-export const RecentlyVisited = (props:RecentlyVisitedPropsType) => {
+export const RecentlyVisited = (props: RecentlyVisitedPropsType) => {
- const {data} = props;
+ const [tabs, set_tabs] = useState<RecentlyVisitedItemsType[]>([]);
- const [tabs, set_tabs] = useState<RecentlyVisitedItemsType[]>([]);
+ const clickHandle = async (val: NavSelecterItemType) => {
+ //更新currentSelectedSys/currentTab触发导航跳转
+ const { systemId = '', menuId = '' } = val;
- const clickHandle = async (val:NavSelecterItemType)=>{
- //更新currentSelectedSys/currentTab触发导航跳转
- await setInitialState((s) => ({ ...s, currentSelectedSys:val as any,currentTab:val}));
- history.push(val.path)
+ await setInitialState((s) => ({ ...s, currentSelectedSys: val as any, currentTab: val }));
+ history.push(val.path);
- },[data])
+ }, [data]);
- <div className='RecentlyVisited'>
- <span className='name'>最近访问</span>
- <div className='tab' onClick={()=>clickHandle(item)} key={index}>{item.name}</div>
+ <div className="RecentlyVisited">
+ <span className="name">最近访问</span>
+ {tabs.map((item, index) => {
+ <div className="tab" onClick={() => clickHandle(item)} key={index}>
+ <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
@@ -2,75 +2,74 @@
* @Date: 2022-05-30 10:49:32
- * @LastEditTime: 2022-07-07 17:53:44
+ * @LastEditTime: 2023-12-27 14:51:13
* @FilePath: /KC-MiddlePlatform/src/pages/index/components/TodoList/index.tsx
//待办事项模块
export type todoItem = {
- id:number;
- status:number;
- taskLevel:number;
- createDate:number;
- content:string;
+ recordTitle: string;
+ id: number;
+ status: number;
+ taskLevel: number;
+ createDate: number;
+ content: string;
export interface TodoList {
- todoList:todoItem[];
- todoListClickHandle?:(id:number)=>void;
+ todoList: todoItem[];
+ todoListClickHandle?: (id: number) => void;
-export const TodoList = (props:TodoList) => {
- const {todoList,todoListClickHandle} = props;
- const [todoLists, set_todoLists] = useState<todoItem[]>([]);
+export const TodoList = (props: TodoList) => {
+ const { todoList, todoListClickHandle } = props;
+ const [todoLists, set_todoLists] = useState<todoItem[]>([]);
- const setTodoClass = (val:todoItem)=>{
- if(val.taskLevel == 3)return 'todoStatus green';
- if(val.taskLevel == 2)return 'todoStatus orange';
- if(val.taskLevel == 1)return 'todoStatus red';
+ const setTodoClass = (val: todoItem) => {
+ if (val.taskLevel == 3) return 'todoStatus green';
+ if (val.taskLevel == 2) return 'todoStatus orange';
+ if (val.taskLevel == 1) return 'todoStatus red';
- const checkBtnHandle = (item:todoItem)=>{
- todoListClickHandle&&todoListClickHandle(item.id)
+ const checkBtnHandle = (item: todoItem) => {
+ todoListClickHandle && todoListClickHandle(item.id);
- set_todoLists(todoList)
- },[todoList])
+ set_todoLists(todoList.splice(0, 4));
+ }, [todoList]);
- <div className='TodoList'>
- <span className='name'>待办事项</span>
- {/* <span className='actBtn'>全部处理</span> */}
- todoLists.map((item, index) => {
- <div className='todoList' key={index}>
- <div className='checkBtn' onClick={()=>checkBtnHandle(item)}></div>
- <div className='status'>
- <div className={setTodoClass(item)}>医务管理系统 / 医资授予</div>
- <span className='date'>{item.createDate}</span>
- <div className='detail' dangerouslySetInnerHTML={{__html:item.content}}></div>
+ <div className="TodoList">
+ <span className="name">待办事项</span>
+ {/* <span className='actBtn'>全部处理</span> */}
+ {todoLists.map((item, index) => {
+ <div className="todoList" key={index}>
+ <div className="checkBtn" onClick={() => checkBtnHandle(item)}></div>
+ <div className="status">
+ <div className={setTodoClass(item)}>{item.recordTitle}</div>
+ <span className="date">{item.createDate ? `${item.createDate}`.replace(/:\d{2}$/, '') : ''}</span>
+ <div className="detail" dangerouslySetInnerHTML={{ __html: item.content }}></div>
+ {todoLists.length == 0 && (
+ <img src={require('../../../../../public/images/empty.png')} alt="" />
+ <span>待办事项已全部处理</span>
.TodoList {
- min-height: 300px;
+ min-height: 348px;
padding-bottom: 24px;
@@ -12,20 +11,20 @@
.actBtn {
@@ -34,21 +33,24 @@
flex-direction: column;
+ height: calc(100% - 48px);
.todoList {
margin-bottom: 24px;
.checkBtn {
- right: 24px;
- top:50%;
+ right: 0px;
+ top: 50%;
margin-top: -16px;
width: 32px;
border-radius: 50%;
background-image: url('./images/gou.png');
background-position: center center;
background-size: 15px 15px;
@@ -64,98 +66,118 @@
.todoStatus {
- background: #E5F9F9;
+ background: #e5f9f9;
border-radius: 6px;
- color: #2FC0C0;
+ color: #2fc0c0;
margin-right: 16px;
padding-right: 10px;
&.green {
- &::before {
- position: relative;
- top:3px;
- display: inline-block;
- content: '';
- width: 16px;
- height: 16px;
- margin-right: 6px;
- background: #2FC0C0;
- background-image: url('./images/exclamationMark.png');
- background-size: 10px 10px;
- background-position: center center;
- background-repeat: no-repeat;
+ // margin-right: 6px;
+ // background: #2FC0C0;
+ // border-radius: 4px;
+ // background-image: url('./images/exclamationMark.png');
+ // background-size: 10px 10px;
+ // background-position: center center;
+ // background-repeat: no-repeat;
&.orange {
- color: #FFAA33;
- background-color: #FCF7F0;
- background: #FFAA33;
+ color: #ffaa33;
+ background-color: #fcf7f0;
+ // background: #FFAA33;
&.red {
- color: #FF6666;
- background-color: #FCF0F0;
- background:#FF6666;
+ color: #ff6666;
+ background-color: #fcf0f0;
+ // background:#FF6666;
.date {
.detail {
+ width: 323px;
- color: #666F80;
- font-weight: bold;
+ color: #666f80;
- margin-bottom: 0;
+ .empty {
+ margin-top: 70px;
+ width: 100px;
+ height: 88px;
@@ -1,245 +1,456 @@
.indexPage {
- height:100%;
+ min-width: 1180px;
.pageContainer {
+ width: calc(100%);
+ flex-direction: row;
- .profileCard {
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- padding: 32px;
+ // .profileCard {
+ // display: flex;
+ // flex-direction: column;
+ // justify-content: flex-start;
+ // padding: 32px;
+ // background: #FFFFFF;
+ // .wraper {
+ // flex: 1;
+ // .avatar {
+ // width: 80px;
+ // height: 80px;
+ // margin-right: 24px;
+ // img {
+ // width: 100%;
+ // .description {
+ // width: calc(100% - 104px);
+ // .rowOne {
+ // flex-direction: row;
+ // justify-content: space-between;
+ // align-items: flex-start;
+ // padding-top: 16px;
+ // .info {
+ // .name {
+ // height: 20px;
+ // font-size: 20px;
+ // font-family: SourceHanSansCN-Bold, SourceHanSansCN;
+ // font-weight: bold;
+ // color: #17181A;
+ // line-height: 30px;
+ // margin-bottom: 16px;
+ // .baseInfo {
+ // height: 14px;
+ // font-size: 14px;
+ // font-family: SourceHanSansCN-Normal, SourceHanSansCN;
+ // font-weight: 400;
+ // color: #666E80;
+ // line-height: 21px;
+ // .staffBaseInfo {
+ // justify-content: flex-end;
+ // .staffBaseInfoSpan {
+ // justify-content: center;
+ // align-items: center;
+ // .spanName {
+ // line-height: 14px;
+ // .spanValue {
+ // line-height: 20px;
+ // &.status {
+ // color: #FFB54D;
+ // .Divider {
+ // height: 24px;
+ // margin-left: 5%;
+ // margin-right: 5%;
+ // margin-top: 10px;
+ // .rowTwo {
+ // margin-top: 45px;
+ // .medicalInfoSpan {
+ // width: 20%;
+ // height: 45px;
+ // margin-right: 10%;
+ // .span {
+ // span {
+ // &:last-child {
+ // margin-bottom: 0;
+ // &:first-child {
+ // width: 40%;
+ // margin-right: 0;
+ // .profileFooter {
+ // padding-top: 25px;
+ // margin-top: 32px;
+ // border-top: 1px solid #DFE3EB;
+ // .flowInstruction {
+ // cursor: pointer;
+ // top: 2px;
+ // // background-image: url('../../../../public/images/alert.png');
+ // // background-size: cover;
+ // .action {
+ // .editProfile {
+ // color: #26334D;
+ // margin-right: 32px;
+ // // background-image: url('../../../../public/images/box.png');
+ // .qualificationApply {
+ // // background-image: url('../../../../public/images/blueFile.png');
+ // .cardTwo {
+ // .cardThree {
+ .left {
+ width: calc(100% - 454px);
+ height: calc(100vh - 80px);
+ min-height: 686px;
- .wraper {
+ background: #fff;
+ .leftTitle {
+ line-height: 24px;
+ font-size: 24px;
+ font-weight: bold;
+ margin-bottom: 12px;
+ .leftTitleSub {
+ color: #525866;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ .leftContent {
- flex: 1;
- .avatar {
- width: 80px;
- height: 80px;
- img {
+ height: calc(100% - 112px);
+ margin-top: 16px;
+ .imgWrap {
+ background-size: cover !important;
+ width: 810px;
+ transition: all 0.3s linear;
- .description {
- width: calc(100% - 104px);
- .rowOne {
- flex-direction: row;
- justify-content: space-between;
- align-items: flex-start;
- padding-top: 16px;
- .info {
- height: 20px;
- font-size: 20px;
- font-family: SourceHanSansCN-Bold, SourceHanSansCN;
- line-height: 30px;
- margin-bottom: 16px;
- .baseInfo {
- height: 14px;
- color: #666E80;
- line-height: 21px;
- .staffBaseInfo {
- justify-content: flex-end;
- .staffBaseInfoSpan {
- justify-content: center;
- align-items: center;
- .spanName {
- line-height: 14px;
- .spanValue {
- line-height: 20px;
- &.status {
- color: #FFB54D;
- .Divider {
- margin-left: 5%;
- margin-right: 5%;
- margin-top: 10px;
+ /* 当屏幕宽度小于或等于 600px */
+ @media screen and (max-width: 1250px) {
+ .imgWrap > img {
+ width: 600px;
- .rowTwo {
- margin-top: 45px;
- .medicalInfoSpan {
+ @media screen and (min-width: 1250px) and (max-width: 1360px) {
+ width: 700px;
+ /* 当屏幕宽度在 601px 到 900px */
+ @media screen and (min-width: 1360px) and (max-width: 1500px) {
+ width: 800px;
+ /* 当屏幕宽度大于 900px */
+ @media screen and (min-width: 1500px) and (max-width: 1760px) {
+ width: 900px;
+ @media screen and (min-width: 1760px) and (max-width: 1920px) {
+ width: 1000px;
+ @media screen and (min-width: 1960px) and (max-width: 2000px) {
+ width: 1200px;
+ @media screen and (min-width: 2000px) {
+ width: 1400px;
+ .right {
+ width: 434px;
+ .cardOne {
+ height: 132px;
+ background: linear-gradient(180deg, #ebf2fc 0%, #fcfeff 100%);
+ box-shadow: 0px 10px 16px 0px rgba(0, 0, 0, 0.02);
+ border: 1px solid #f7fbff;
+ .welcomBg {
+ z-index: 1;
+ top: 0;
+ left: 0;
+ .inner {
+ z-index: 9;
+ .userId {
+ top: -7px;
+ right: -15.5px;
+ color: #5c7599;
+ padding-left: 16px;
+ padding-right: 8px;
+ background: linear-gradient(180deg, #e8f1fc 0%, #fcfeff 100%);
+ border-radius: 100px 0px 0px 100px;
+ opacity: 0.8;
+ .cardOneTitle {
+ margin-bottom: 25px;
+ .row {
- width: 20%;
- height: 45px;
- margin-right: 10%;
- .span {
+ .label {
+ width: 50%;
- span {
+ text-align: left;
+ top: -1px;
+ margin-right: 4px;
- &:last-child {
- width: 40%;
+ margin-top: 14px;
- .profileFooter {
- padding-top: 25px;
- margin-top: 32px;
- border-top: 1px solid #DFE3EB;
- .flowInstruction {
- cursor: pointer;
- top: 2px;
- margin-right: 8px;
- // background-image: url('../../../../public/images/alert.png');
- // background-size: cover;
- .action {
- .editProfile {
- color: #26334D;
- margin-right: 32px;
- top: 3px;
- // background-image: url('../../../../public/images/box.png');
- .qualificationApply {
- // background-image: url('../../../../public/images/blueFile.png');
+ .cardTwo {
+ .cardThree {
+ // height: calc(100% - 340px);
+ background-color: #fff;
- .cardTwo {
- .cardThree {
* @Date: 2021-11-10 09:33:30
- * @LastEditTime: 2022-09-08 09:06:07
+ * @LastEditTime: 2024-03-28 17:26:40
* @FilePath: /KC-MiddlePlatform/src/pages/index.tsx
@@ -9,16 +9,17 @@
import { useModel, history, Location, Helmet } from 'umi';
import './index.less';
-import { Skeleton, Divider } from 'antd';
-import { useState,useEffect } from 'react';
+import { Skeleton, Divider, Modal } from 'antd';
+import { useState, useEffect } from 'react';
import avatar from '../../../public/images/avatar.png';
import { FastEntry, FastEntryTabType } from './components/FastEntry';
import { RecentlyVisited, RecentlyVisitedItemsType } from './components/RecentlyVisited';
import { todoItem, TodoList } from './components/TodoList';
-import { getUserIndexData, todoListAct, UserInfo } from '@/service';
+import { getSysParamsByCode, getUserIndexData, todoListAct, UserInfo } from '@/service';
import { MsgRecord } from './components/MsgRecord';
+import { getParamsManaTableData } from '../platform/setting/paramsMana/service';
export interface IndexPageType {
location: Location;
@@ -28,7 +29,7 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
const {
systemLists, //当前医院可选子系统列表
setInitialState,
- userData
+ userData,
} = useModel('@@initialState', (model) => {
systemLists: model.initialState?.systemLists,
@@ -37,145 +38,195 @@ const IndexPage: React.FC<IndexPageType> = ({ location }) => {
- const [loading, setLoading] = useState(false);
- const [userInfo,set_userInfo] = useState<UserInfo>();
- const [fastEntry,set_fastEntry] = useState<FastEntryTabType[]>([]);
- const [recentlyVisitedList,set_recentlyVisitedList] = useState<RecentlyVisitedItemsType[]>([]);
- const [todoList,set_todoList] = useState<todoItem[]>([]);
- const [msgRecord,set_msgRecord] = useState([]);
- const getIndexPageDataFunc =async () => {
- const resp = await getUserIndexData();
- set_userInfo(resp.userInfo);
- const fastEntryList = resp.fastEntrance.map((item:any)=>({
- name:item.name,
- path:item.path,
- menuId:item.menuId,
- systemId:item.systemId
- set_fastEntry(fastEntryList);
- set_todoList(resp.todoList.map((t:any)=>({
- id:t.id,
- status:1,
- content:t.content,
- createDate:t.createDate,
- taskLevel:t.taskLevel,
- })));
- set_msgRecord(resp.messageRecords.map((t:any)=>({
- title:t.recordTitle,
- date:t.createDate,
- resolveTime:t.resolveTime,
- isProcess:t.isProcess,
- content:t.content
+ const [userInfo, set_userInfo] = useState<UserInfo>();
+ const [fastEntry, set_fastEntry] = useState<FastEntryTabType[]>([]);
+ const [recentlyVisitedList, set_recentlyVisitedList] = useState<RecentlyVisitedItemsType[]>([]);
+ const [todoList, set_todoList] = useState<todoItem[]>([]);
+ const [msgRecord, set_msgRecord] = useState([]);
+ const [specialPageUrl, setspecialPageUrl] = useState<string | undefined>(undefined);
+ const [leftImgUrl, set_leftImgUrl] = useState<string | undefined>(undefined);
+ const [leftBgImgUrl, set_leftBgImgUrl] = useState<string | undefined>(undefined);
+ const [iframeLoading, set_iframeLoading] = useState(false);
+ const [allParams, set_allParams] = useState<any[]>([]);
+ const [title, set_title] = useState<string | undefined>(undefined);
+ const [welcomTitle, set_welcomTitle] = useState('欢迎进入医管平台');
+ const onLoadhandle = () => {
+ set_iframeLoading(false);
+ const getIndexPageDataFunc = async () => {
+ const resp = await getUserIndexData();
+ set_userInfo(resp.userInfo);
+ set_leftImgUrl(resp.indexUrl ? resp.indexUrl.split('|')[0] : undefined);
+ set_leftBgImgUrl(resp.indexUrl ? resp.indexUrl.split('|')[1] : undefined);
+ localStorage.setItem('userInfo', JSON.stringify(resp.userInfo));
+ const fastEntryList = resp.fastEntrance.map((item: any) => ({
+ name: item.name,
+ path: item.path,
+ menuId: item.menuId,
+ systemId: item.systemId,
+ type: item.type,
+ contentType: item.contentType,
+ url: item.url,
+ set_fastEntry(fastEntryList);
+ set_todoList(
+ resp.todoList.map((t: any) => ({
+ id: t.id,
+ status: 1,
+ content: t.content,
+ createDate: t.createDate,
+ taskLevel: t.taskLevel,
+ recordTitle: t.recordTitle,
+ })),
+ set_msgRecord(
+ resp.messageRecords.map((t: any) => ({
+ title: t.recordTitle,
+ date: t.createDate,
+ resolveTime: t.resolveTime,
+ isProcess: t.isProcess,
+ const todoListClickHandle = async (id: number) => {
+ const resp = await todoListAct([id]);
+ getIndexPageDataFunc();
+ const setIframeUrl = async (allParams: any[]) => {
+ const needItem = allParams.filter((a: any) => a.code == '1644270043527254016');
+ const userData = localStorage.getItem('userData');
+ let token = '';
- const todoListClickHandle = async (id:number)=>{
- const resp = await todoListAct([id]);
- getIndexPageDataFunc();
+ if (userData) {
+ const { youshuToken } = JSON.parse(userData);
+ token = youshuToken;
+ if (needItem.length > 0) {
+ setspecialPageUrl(`http://eastern1.kcim-bi.163yun.com/dash/integration/56?rid=${needItem[0].value}&toolbar=[]&hideTitle=true&hideScaleBar=false&&scale=screen&hidePageBar=false&token=${token}`);
+ set_allParams(resp);
+ if (allParams) {
+ setIframeUrl(allParams);
+ allParams.forEach((item) => {
+ if (item.code == '1739124039835848704') {
+ set_title(item.value);
+ set_welcomTitle(item.value);
+ }, [allParams]);
getIndexPageDataFunc();
const visitedPaths = JSON.parse(t);
set_recentlyVisitedList(visitedPaths);
+ // const url = `${spacialPage[0].url}&token=${youshuToken}`;
<div className="indexPage">
<Helmet>
- <title>欢迎进入医管平台</title>
+ <title>{welcomTitle}</title>
</Helmet>
- <div className='pageContainer'>
- <div className="profileCard">
- <Skeleton loading={loading} active avatar>
- <div className='wraper'>
- <div className="avatar">
- <img src={avatar} alt="头像" />
+ <div className="pageContainer">
+ <div style={{ padding: 8 }}>
+ <div className="leftTitle">{title ? title.split('|')[0] : '默认标题'}</div>
+ <div className="leftTitleSub">{title ? title.split('|')[1] : '默认标题'}</div>
+ <div className="leftContent">
+ {specialPageUrl && (
+ <div className="iframe" style={{ width: '100%' }}>
+ <Skeleton loading={iframeLoading} paragraph={{ rows: 50 }} active />
+ <iframe onLoad={() => onLoadhandle()} style={{ width: '100%', height: 'calc(100vh - 180px)', border: 'none' }} src={specialPageUrl}></iframe>
+ {!specialPageUrl && (
+ <div className="imgWrap" style={{ width: '100%', background: `url(${leftBgImgUrl})` }}>
+ <img src={leftImgUrl} alt="" />
- <div className="description">
- <div className="rowOne">
- <div className="info">
- <div className="name">{userInfo?.name}</div>
- <div className="baseInfo">
- {`${userInfo?.gender} | ${userInfo?.title?userInfo?.title:'-'} | ${userInfo?.major?userInfo?.major:'-'}`}
+ <div className="cardOne">
+ <img className="welcomBg" src={require('../../../public/images/welcom_bg.png')} alt="" />
+ <div className="inner">
+ <span className="userId">{userInfo?.account}</span>
+ <div className="cardOneTitle">{`欢迎回来,${userInfo?.name}`}</div>
+ <div className="row">
+ <div className="label">
+ <img src={require('../../../public/images/icon-keshi.png')} alt="" />
+ <span>科室</span>
+ {userInfo?.departmentName ? userInfo?.departmentName : '-'}
- <div className='staffBaseInfo'>
- <div className='staffBaseInfoSpan'>
- <span className='spanName'>人员工号</span>
- <span className='spanValue'>{userInfo?.account?userInfo?.account:'-'}</span>
- <Divider type="vertical" className='Divider' />
- <span className='spanName'>人员类别</span>
- <span className='spanValue'>{userInfo?.jobTitle?userInfo?.jobTitle:'-'}</span>
- <span className='spanName'>所属科室</span>
- <span className='spanValue'>{userInfo?.departmentName?userInfo?.departmentName:'-'}</span>
- <span className='spanName'>进院日期</span>
- <span className='spanValue'>{userInfo?.entryTime?`${new Date(userInfo?.entryTime).getFullYear()}-${(new Date(userInfo?.entryTime).getMonth()+1)>10?(new Date(userInfo?.entryTime).getMonth()+1):'0'+(new Date(userInfo?.entryTime).getMonth()+1)}-${(new Date(userInfo?.entryTime).getDate())>10?(new Date(userInfo?.entryTime).getDate()):'0'+(new Date(userInfo?.entryTime).getDate())}`:'-'}</span>
+ <img src={require('../../../public/images/icon-zhicheng.png')} alt="" />
+ <span>职称</span>
+ {userInfo?.title ? userInfo?.title : '-'}
- <div className="rowTwo">
- <div className='medicalInfoSpan'>
- <div className='span'>资格证号:<span>{userInfo?.qualificationCertificateNo?userInfo?.qualificationCertificateNo:'-'}</span></div>
- <div className='span'>执业证号:<span>{userInfo?.practiceCertificateNo?userInfo?.practiceCertificateNo:'-'}</span></div>
- <div className='span'>医师级别:<span>{userInfo?.doctorLevel?userInfo?.doctorLevel:'-'}</span></div>
- <div className='span'>执业状态:<span>{userInfo?.practiceStatus?userInfo?.practiceStatus:'-'}</span></div>
+ <img src={require('../../../public/images/icon-leibie.png')} alt="" />
+ <span>类别</span>
+ {userInfo?.userCate ? userInfo?.userCate : '-'}
- <div className='span'>执业科目:<span>{userInfo?.practiceCate?userInfo?.practiceCate:'-'}</span></div>
- <div className='span'>备注:<span>{userInfo?.remark?userInfo?.remark:'-'}</span></div>
+ <img src={require('../../../public/images/icon-gangwei.png')} alt="" />
+ <span>岗位</span>
+ {userInfo?.position ? userInfo?.position : '-'}
- <div className='span'>执业类别:<span>{userInfo?.userCate?userInfo?.userCate:'-'}</span></div>
- </Skeleton>
- <div className='cardTwo '>
- <FastEntry data={fastEntry} />
- <RecentlyVisited data={recentlyVisitedList} />
- <div className='cardThree'>
- <TodoList todoList={todoList} todoListClickHandle={todoListClickHandle} />
- <MsgRecord list={msgRecord}/>
+ <div className="cardTwo">
+ <FastEntry data={fastEntry} />
+ <div className="cardThree">
+ <TodoList todoList={todoList} todoListClickHandle={todoListClickHandle} />
@@ -1,14 +1,14 @@
* @Date: 2021-11-09 14:58:08
- * @LastEditTime: 2023-02-13 11:35:50
+ * @LastEditTime: 2024-03-28 17:50:54
* @FilePath: /KC-MiddlePlatform/src/pages/login/index.tsx
import React, { useRef, useEffect, useState, Children, ReactEventHandler } from 'react';
-import { Select, message, Row, Col } from 'antd';
+import { Select, message, Row, Col, Modal } from 'antd';
@@ -19,8 +19,10 @@ import logo from '../../../public/images/kclogo_colorful.png';
import KCSelect from '@/components/kc-select';
-import { getHospConfigBySign, login } from '@/service/login';
+import { getHospConfigBySign, getLastLoginSys, getLoginTipType, login } from '@/service/login';
import Divider from '@ant-design/pro-card/lib/components/Divider';
+import { getSysParamsByCode } from '@/service';
const { Option } = Select;
@@ -30,40 +32,71 @@ export interface LoginPageType {
const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
const loginPageRef = useRef<HTMLDivElement>(null);
- const [subHospList, setSubHospList] = useState<{ name: string; value: string | number }[]>([]); //分院列表
+ const [subHospList, setSubHospList] = useState<
+ loadType: number;
+ id: string;
+ hospAbbreviation: any;
+ value: string | number;
+ }[]
+ >([]); //分院列表
const [ifLoading, setIfLoading] = useState(false);
// const [systemList, setSystemList] = useState<userRelationInfo.OwnAppsItem[]>([]); //可选平台列表
const [currentHospName, setCurrentHospName] = useState('欢迎进入医务管理系统');
const [windowWidth, set_windowWidth] = useState(0);
const [ifShowLeftBlock, set_ifShowLeftBlock] = useState(true);
+ const [currentSelectedSubHop, set_currentSelectedSubHop] = useState<any | undefined>({
+ id: undefined,
+ loginTips: '',
+ loginPic: '',
+ }); //当前选中的院区
+ const [hospSign, set_hospSign] = useState<undefined | string>(undefined); //登陆用的hospSign
+ const initLoginPageInfo = async () => {
+ return [];
//获取当前账号分院列表
const getSubHospFunc = async () => {
- const hospSign = history.location.query?.hospSign as string;
if (hospSign) {
const data = await getHospConfigBySign(hospSign);
- if(data as any instanceof Array){
+ if ((data as any) instanceof Array) {
setSubHospList(
- data.map((t) => ({
- name: t.name,
- value: t.hospSign,
- })),
+ data.map((t) => {
+ const temp = {
+ name: t.name,
+ value: t.hospSign,
+ hospAbbreviation: t.hospAbbreviation,
+ loadType: t.loadType,
+ loginPic: t.loginPic ? t.loginPic : '',
+ loginTips: t.loginTips ? t.loginTips : '',
+ systemName: t.systemName,
+ if (t.hospSign == hospSign) {
+ setCurrentHospName(temp.systemName);
+ set_currentSelectedSubHop(temp);
+ localStorage.setItem('currentSelectedSubHop', JSON.stringify(temp));
+ localStorage.setItem('hospAbbreviation', temp.hospAbbreviation);
+ localStorage.setItem('currentHospName', temp.systemName);
+ return temp;
+ }),
- setCurrentHospName(data[0].systemName);
const onFinish = async (values: LoginPageTypes.LoginInfo) => {
setIfLoading(true);
- const hospSign = localStorage.getItem('hospSign');
if (!hospSign) {
message: '网址标记缺失,请检查网址!',
@@ -79,11 +112,54 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
setIfLoading(false);
if (resp) {
localStorage.setItem('userData', JSON.stringify(resp));
+ localStorage.setItem('tokenExpired', 'false');
setInitialState((s) => ({ ...s, userData: resp }));
+ const lastLoginSysData = await getLastLoginSys({ hospId: currentSelectedSubHop.id, userId: resp.userId });
+ if (lastLoginSysData) {
+ history.replace(lastLoginSysData.path);
+ localStorage.setItem('currentSelectedTab', JSON.stringify({ ...lastLoginSysData, menuId: lastLoginSysData.systemId }));
+ // if(values.password == '123456'){
+ // //如果密码为默认密码时
+ // const loginTipeType = await getSysParamsByCode('','1688483840064098304');
+ // if(loginTipeType){
+ // const needItem = loginTipeType.filter((a:any)=>a.code == '1688483840064098304');
+ // if(needItem.length>0){
+ // if(needItem[0].value == 2){
+ // Modal.confirm({
+ // title:'提醒',
+ // content:'您的账号存在密码泄露风险,请尽快修改密码!',
+ // okText:'去更改',
+ // cancelText:'稍后',
+ // onOk(...args) {
+ // history.replace('/personalCenter');
+ // })
+ // if(needItem[0].value == 3){
+ // Modal.warn({
+ // content:'您的账号存在密码泄露风险,请先修改密码!',
@@ -92,88 +168,86 @@ 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);
setCurrentHospName(title);
}, [title]);
- if (windowWidth <= 1000&&windowWidth != 0) {
+ if (windowWidth <= 1000 && windowWidth != 0) {
set_ifShowLeftBlock(false);
set_ifShowLeftBlock(true);
}, [windowWidth]);
+ if (hospSign) {
+ location.pathname == '/login' && getSubHospFunc();
+ }, [hospSign]);
//根据hospSign获取分院信息
- location.pathname == '/login' && getSubHospFunc();
setInitialState((s) => ({ ...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);
- return ()=>{
- window.removeEventListener('resize',handleResize);
+ window.removeEventListener('resize', handleResize);
- <div className="loginPage" >
+ <div className="loginPage">
<title>{currentHospName}</title>
{location.pathname == '/login' ? (
<Row style={{ height: '100%' }}>
- ifShowLeftBlock && (
- <Col flex="500px">
- <div className='topLogo'>
- <img className='logo' src={logo} alt="康程智医" />
- <div className='logoDesc'>助力医疗机构高质量发展</div>
- <img className='loginbanner' src={require('../../../public/images/loginBannner.png')} alt="" />
+ {ifShowLeftBlock && (
+ <Col flex="500px">
+ <div className="topLogo">
+ <img className="logo" src={currentSelectedSubHop?.loginPic} alt="康程智医" />
+ <div className="logoDesc">{(currentSelectedSubHop?.loginTips.split('|'))[0]}</div>
- </Col>
+ <img className="loginbanner" src={require('../../../public/images/loginBannner.png')} alt="" />
+ </Col>
<Col flex="auto">
<div className="rightLoginArea">
- !ifShowLeftBlock && (
+ {!ifShowLeftBlock && (
<div className="subHospSelector">
{subHospList.length > 0 && (
<KCSelect
allowClear={false}
style={{ width: 180 }}
- defaultValue={subHospList[0].value}
- onSelect={(val:any)=>{
- localStorage.removeItem('hospSign');
- localStorage.setItem('hospSign', val);
+ defaultValue={hospSign}
+ onSelect={(val: any, option) => {
+ set_hospSign(val);
+ localStorage.setItem('hospAbbreviation', option.item.hospAbbreviation);
+ localStorage.setItem('currentSelectedSubHop', JSON.stringify(option.item));
+ set_currentSelectedSubHop(option.item);
suffixIcon={<img style={{ width: '10px', height: '6px' }} src={require('../../../public/images/arrow.png')} />}
{subHospList.map((item) => {
- <Option value={item.value} key={item.value}>
+ <Option value={item.value} item={item} key={item.value}>
{item.name}
</Option>
@@ -183,7 +257,6 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
<div className="systemName">{currentHospName}</div>
<Form onFinish={onFinish}>
<Form.Item name="account" rules={[{ required: true, message: '请输入用户名!' }]}>
<Input className="input" placeholder="请输入用户名" />
</Form.Item>
@@ -202,12 +275,11 @@ const LoginPage: React.FC<LoginPageType> = ({ location, children, title }) => {
<Checkbox className="checkBtn">记住密码</Checkbox>
</Form.Item> */}
</Form>
- <div className='bottomCopyright'>© 2022 康程智医(成都)技术部出品</div>
- <div className='versionInfo'>精益管理决策平台 V1.0</div>
+ <div className="bottomCopyright">{(currentSelectedSubHop?.loginTips.split('|'))[1]}</div>
+ <div className="versionInfo">{(currentSelectedSubHop?.loginTips.split('|'))[2]}</div>
</Col>
</Row>
) : (
children
)}
* @Date: 2022-03-03 17:42:10
- * @LastEditTime: 2022-07-21 16:13:32
+ * @LastEditTime: 2023-06-12 16:14:59
* @FilePath: /KC-MiddlePlatform/src/pages/personalCenter/components/security.tsx
@@ -104,6 +104,7 @@ const SecurityView: React.FC = () => {
title: '密码修改成功,前往重新登录?',
closable: false,
+ okText:'确定',
if (initialState?.logout) {
initialState.logout();
@@ -1,6 +1,7 @@
import React, { useState, useRef, useLayoutEffect } from 'react';
import { GridContent } from '@ant-design/pro-layout';
import { Menu } from 'antd';
+import { history } from 'umi';
import BaseView from './components/base';
import BindingView from './components/binding';
import NotificationView from './components/notification';
@@ -101,6 +102,15 @@ const PAGE_NAME_UPPER_CAMEL_CASE: React.FC = () => {
</Menu>
<div className={styles.right}>
+ <div className={styles.gobacktoindex} onClick={()=>{
+ const lastLoginSysData = localStorage.getItem('currentSelectedTab');
+ if(lastLoginSysData){
+ const {path} = JSON.parse(lastLoginSysData);
+ history.replace(path);
+ }else{
+ }}>返回</div>
<div className={styles.title}>{menuMap[initConfig.selectKey]}</div>
{renderChildren()}
@@ -21,6 +21,7 @@
flex: 1;
padding: 8px 40px;
.title {
@@ -30,6 +31,20 @@
font-size: 20px;
line-height: 28px;
+ .gobacktoindex {
+ top:16px;
+ padding: 0 8px;
.rightListItem {
background-color: #eee;
* @Date: 2022-01-06 15:25:39
- * @LastEditTime: 2023-03-23 16:41:41
+ * @LastEditTime: 2024-01-16 16:49:31
* @FilePath: /KC-MiddlePlatform/src/pages/platform/_layout.tsx
@@ -13,10 +13,17 @@ import ProLayout, { PageContainer } from '@ant-design/pro-layout';
import { getPlatformMenu, getSpecifyMenuDetail } from '@/service/menu';
import { TreeItemType } from '@/utils';
-import { Iframe, SpacicalPageParamsType } from '@/typings';
+import { SpacicalPageParamsType } from '@/typings';
-import IconFont from '@ant-design/icons/lib/components/IconFont';
-import { FileOutlined, FolderOutlined, SmileOutlined } from '@ant-design/icons';
+import Icon, { FileOutlined, FolderOutlined, createFromIconfontCN } from '@ant-design/icons';
+import { getAllParams } from '@/service';
+import '../../../public/zhongtaiC';
export default function Layout({ children, location, route, history, match, ...rest }: IRouteComponentProps) {
@@ -26,8 +33,9 @@ export default function Layout({ children, location, route, history, match, ...r
const [isShowPageMenu, set_isShowPageMenu] = useState(true);
const [isEmpty, set_isEmpty] = useState(false);
- //const isShowMenu = localStorage.getItem('isChildShowMenu');
- // console.log({ children, location, route, history, match});
+ const [collapsed, set_collapsed] = useState(false);
+ const [pageUrl, set_pageUrl] = useState<string | undefined>(undefined);
const { pathname } = location;
@@ -37,23 +45,41 @@ export default function Layout({ children, location, route, history, match, ...r
set_isShowPageMenu(false);
const isShowMenu = localStorage.getItem('isChildShowMenu');
- set_isShowPageMenu(isShowMenu == 'true')
+ set_isShowPageMenu(isShowMenu == 'true');
if (location.query.menuId) {
setEmptyPageContent(location.query.menuId as string);
}, [location]);
+ const handleResize = () => {
+ if (window.innerWidth <= 1280) {
+ // 自定义触发宽度为 800px
+ set_collapsed(true);
+ set_collapsed(false);
+ // 初始化
+ handleResize();
+ // 监听窗口大小变化
+ window.addEventListener('resize', handleResize);
+ // 清除监听器
const adjustIframe = () => {
// var ifm:any = document.getElementById("bi_iframe");
@@ -61,35 +87,127 @@ export default function Layout({ children, location, route, history, match, ...r
// ifm.height=document.documentElement.clientHeight;
// ifm.width=document.documentElement.clientWidth;
// }
+ const addTokenToUrl = (url: string, token = '') => {
+ // 检查 URL 中是否有查询字符串
+ url = url.trim();
+ if (url.includes('?')) {
+ // 检查是否已经有 token 参数
+ if (!url.includes('token=')) {
+ // 添加 &token=,因为 URL 中已经有其他查询参数
+ url += `&token=${token}`;
+ // URL 中没有查询参数,所以添加 ?token=
+ url += `?token=${token}`;
+ return url;
+ if (initialState?.currentSelectedSys) {
+ const { type, url, contentType } = initialState.currentSelectedSys;
+ const { token } = JSON.parse(userData as string);
+ return <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={addTokenToUrl(url as string, token)} onLoad={() => adjustIframe()}></iframe>;
//临时演示处理
if (location.pathname == '/platform/costMana') {
- return <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src="http://112.124.59.133:4000/platformMana/roleManage?hospSign=dOBHdoPmJgPGnMSH" onLoad={() => adjustIframe()} ></iframe>;
+ //临时解决未嵌入成本核算,而实现访问的效果
+ const getToken = async () => {
+ const resp = await getAllParams();
+ const needItem = resp.filter((a: any) => a.code == '1647777324889935872');
+ set_pageUrl(`http://47.96.149.190:8000/platformMana/roleManage?hospSign=dOBHdoPmJgPGnMSH&token=${needItem[0].value}`);
+ getToken();
+ return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
+ if (location.pathname == '/platform/costMana2') {
+ const needItem = resp.filter((a: any) => a.code == '1733034722981974016');
+ set_pageUrl(`http://47.96.149.190:8000/platformMana/roleManage?hospSign=QgqzJxUR5reLh5ER&token=${needItem[0].value}`);
+ if (location.pathname == '/platform/Budget') {
+ const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=budget/index`;
+ if (location.pathname == '/platform/DRG') {
+ const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=drgs/index`;
+ if (location.pathname == '/platform/DIP') {
+ const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=dips/index`;
+ if (location.pathname == '/platform/baokangCostApp') {
+ const pageUrl = `https://test.baokangyiguan.com/index/apiLogin?username=admin&url=cost/index `;
style={{
height: 'calc(100vh - 50px)',
- iconfontUrl="//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js"
+ //iconfontUrl="//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js"
logoStyle={{
display: 'none',
- location={{
- }}
+ location={{}}
headerContentRender={false}
headerRender={false}
- siderWidth={isShowPageMenu ? 220 : 0}
+ siderWidth={isShowPageMenu ? 200 : 0}
+ breakpoint={false}
disableContentMargin
+ collapsed={collapsed}
+ onCollapse={(collapsed) => set_collapsed(collapsed)}
+ collapsedButtonRender={() => {
+ className="collapsedBtn"
+ onClick={() => {
+ set_collapsed(collapsed ? false : true);
+ }}
+ <IconFont style={{ display: 'inline-block' }} className="menuCollapseIcon" type={collapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'} />
menuItemRender={(item, dom) => {
<a
onClick={() => {
@@ -98,7 +216,7 @@ export default function Layout({ children, location, route, history, match, ...r
menuProps={{
openKeys: [...openKeys],
@@ -115,11 +233,9 @@ export default function Layout({ children, location, route, history, match, ...r
autoClose: false,
params: {
- initialState
+ initialState,
if (initialState && initialState.currentSelectedSys) {
const { systemId, menuId, path } = initialState.currentSelectedSys;
if (systemId || menuId) {
@@ -134,8 +250,8 @@ export default function Layout({ children, location, route, history, match, ...r
if (t.isHomepage) {
homePage = t;
- if (t[key] && t[key] == 1) {
- //非一般页面
+ if (t[key] == 1 || t[key] == 2 || t[key] == 3) {
+ //网易有数页面
result.push({
contentType: t[key],
path: t['path'],
@@ -143,6 +259,15 @@ export default function Layout({ children, location, route, history, match, ...r
url: t['youshuUrl'],
+ if (t[key] == 5) {
+ //蓝湖静态展示页面
+ result.push({
+ contentType: t[key],
+ path: t['path'],
+ reportId: t['reportId'],
+ url: t['softUrl'],
if (t.children && t.children.length > 0) {
looper(t.children, key);
@@ -152,7 +277,6 @@ export default function Layout({ children, location, route, history, match, ...r
return result;
const _menu = getVFromTree(menuData, 'contentType');
setInitialState((t) => ({ ...t, spacicalPageParamsType: _menu }));
@@ -161,96 +285,112 @@ export default function Layout({ children, location, route, history, match, ...r
set_openKeys([homePage.key]);
set_selectedKeys([homePage.key]);
history.push(homePage.path);
if (path == '/platform') {
const selectedKeys = localStorage.getItem('selectedKeys');
const openKeys = localStorage.getItem('openKeys');
- if (selectedKeys&&openKeys) {
+ if (selectedKeys && openKeys) {
const _selectedKeys = JSON.parse(selectedKeys);
const _openKeys = JSON.parse(openKeys);
set_openKeys(_openKeys);
set_selectedKeys(_selectedKeys);
if (menuData[0].children && menuData[0].children.length > 0) {
const childs = menuData[0].children;
set_openKeys([menuData[0].key]);
set_selectedKeys([childs[0].key]);
- localStorage.setItem('openKeys',JSON.stringify([menuData[0].key]));
- localStorage.setItem('selectedKeys',JSON.stringify([childs[0].key]));
+ localStorage.setItem('openKeys', JSON.stringify([menuData[0].key]));
+ localStorage.setItem('selectedKeys', JSON.stringify([childs[0].key]));
history.push(`${childs[0].path}`);
+ if (menuData[0]) {
+ set_openKeys([menuData[0].key]);
+ set_selectedKeys([menuData[0].key]);
+ localStorage.setItem('selectedKeys', JSON.stringify([menuData[0].key]));
+ history.push(`${menuData[0].path}`);
- // console.log({homePage})
- // return [...menuData, {
- // name: 'SQL编辑器',
- // path: '/platform/sqlEditer'
- // }];
- const addIcon = (arr: any) => arr.map((item: any) => (item.children ? {
- ...item,
- icon: <FolderOutlined />,
- children: addIcon(item.children)
- } : {
- icon: <FileOutlined />,
- }))
- const result = addIcon(menuData);
+ const addIcon = (arr: any) =>
+ arr.map((item: any) =>
+ item.children
+ ? {
+ ...item,
+ icon: <FolderOutlined />,
+ children: addIcon(item.children),
+ : {
+ icon: <FileOutlined />,
+ const imgNode = (props: any) => {
+ return <IconFont type="icon-pingtaiguanli" />;
+ const systemSet = (props: any) => {
+ return <IconFont type="icon-xitongshezhi" />;
- return [...result];
+ function addIconToPath(node: any) {
+ if (node.name == '超管设置') {
+ node.icon = <Icon component={imgNode} />;
+ if (node.name == '系统设置') {
+ node.icon = <Icon component={systemSet} />;
+ if (node.children) {
+ node.children.forEach((child: any) => addIconToPath(child));
+ const result = addIcon(menuData);
+ result.forEach((item: any) => {
+ addIconToPath(item);
+ return [...result];
- onPageChange={(location) => { }}
+ onPageChange={(location) => {}}
layout="side"
navTheme="light"
- isEmpty && (
- <div className='emptyContainer' style={{ textAlign: 'center', paddingTop: 100 }}>
+ <div className="emptyContainer" style={{ textAlign: 'center', paddingTop: 100 }}>
+ {!isEmpty && (
+ <PageContainer
+ className="kcmpPageContainer"
+ header={{
+ style={{
+ margin: 0,
+ <Helmet>
+ <title>精益管理中台</title>
+ </Helmet>
+ <div className="page" style={{ height: 'calc(100vh - 80px)', overflowY: 'scroll' }}>
+ {children}
- !isEmpty && (
- <PageContainer
- className="kcmpPageContainer"
- header={{
- title: false,
- style={{
- margin: 0,
- >
- <Helmet>
- <title>精益管理中台</title>
- </Helmet>
- <div className="page" style={{ height: 'calc(100vh - 80px)', overflowY: 'scroll' }}>
- {children}
- </PageContainer>
+ </PageContainer>
@@ -2,168 +2,140 @@
* @Date: 2022-07-06 09:31:32
- * @LastEditTime: 2023-01-05 09:19:27
+ * @LastEditTime: 2023-08-10 15:21:18
* @FilePath: /KC-MiddlePlatform/src/pages/platform/components/TreeEditer/index.tsx
-import React, { Key, useEffect, useState } from 'react'
-import { Tree, Radio,Divider } from 'antd';
+import { Tree, Radio, Divider } from 'antd';
import type { DataNode } from 'antd/lib/tree';
import { getMenuDirectory, MenuItemDataType } from '@/service/menu';
import { TagsOutlined } from '@ant-design/icons';
const { TreeNode } = Tree;
const getTreeNode = (data: MenuItemDataType[]) => {
- if (data && data.length > 0) {
- return data.map((item) => {
- if (item.children) {
- <TreeNode key={item.menuId} title={item.name}>
- {getTreeNode(item.children)}
- </TreeNode>
- );
- <TreeNode
- key={item.menuId}
- title={item.name}
- switcherIcon={<TagsOutlined />} // TreeNode这个Tree的子组件居然存在SwitcherIcon属性.
- />
- return [];
+ if (data && data.length > 0) {
+ return data.map((item) => {
+ if (item.children) {
+ <TreeNode key={item.menuId} title={item.name}>
+ {getTreeNode(item.children)}
+ </TreeNode>
+ <TreeNode
+ key={item.menuId}
+ title={item.name}
+ switcherIcon={<TagsOutlined />} // TreeNode这个Tree的子组件居然存在SwitcherIcon属性.
+ />
-export type TreeEditerValueType = {actType:'COPY'|'MOVE';selectedKeysValue: Key[]}
+export type TreeEditerValueType = { actType: 'COPY' | 'MOVE'; selectedKeysValue: Key[] };
export interface TreeEditerPropsType {
- onChange?: (data:TreeEditerValueType) => void;
+ onChange?: (data: TreeEditerValueType) => void;
function TreeEditer(props: TreeEditerPropsType) {
- const { onChange } = props;
- const [treeData, set_treeData] = useState<MenuItemDataType[]>([]);
- const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
- const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
- const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
- const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
- const [actType,set_actType] = useState<'COPY'|'MOVE'>('COPY');
- // const onExpand = (expandedKeysValue: React.Key[]) => {
- // console.log('onExpand', expandedKeysValue);
- // // if not set autoExpandParent to false, if children expanded, parent can not collapse.
- // // or, you can remove all expanded children keys.
- // setExpandedKeys(expandedKeysValue);
- // setAutoExpandParent(false);
- // };
- // const onCheck = (checkedKeysValue:any) => {
- // console.log('onCheck', checkedKeysValue);
- // setCheckedKeys(checkedKeysValue);
- const onSelect = (selectedKeysValue: React.Key[], info: any) => {
- setSelectedKeys(selectedKeysValue);
- onChange && onChange({actType,selectedKeysValue});
+ const { onChange } = props;
+ const [treeData, set_treeData] = useState<MenuItemDataType[]>([]);
+ const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
+ const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
+ const [actType, set_actType] = useState<'COPY' | 'MOVE'>('COPY');
+ // const onExpand = (expandedKeysValue: React.Key[]) => {
+ // console.log('onExpand', expandedKeysValue);
+ // // if not set autoExpandParent to false, if children expanded, parent can not collapse.
+ // // or, you can remove all expanded children keys.
+ // setExpandedKeys(expandedKeysValue);
+ // setAutoExpandParent(false);
+ // };
+ // const onCheck = (checkedKeysValue:any) => {
+ // console.log('onCheck', checkedKeysValue);
+ // setCheckedKeys(checkedKeysValue);
+ const onSelect = (selectedKeysValue: React.Key[], info: any) => {
+ setSelectedKeys(selectedKeysValue);
+ onChange && onChange({ actType, selectedKeysValue });
+ const radioOnchange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ if (e.target.value == 'COPY') set_actType('COPY');
+ if (e.target.value == 'MOVE') set_actType('MOVE');
+ const getTreeData = async () => {
+ let expandedKeys: (number | string)[] = [];
+ const convertData = (data: Array<any>) => {
+ data.forEach((item) => {
+ item.title = item.name;
+ item.key = item.menuId;
+ if (!item.children || item.children.length == 0) {
+ expandedKeys.push(item.menuId);
+ convertData(item.children);
- const radioOnchange = (e:React.ChangeEvent<HTMLInputElement>)=>{
- if(e.target.value == 'COPY')set_actType('COPY');
- if(e.target.value == 'MOVE')set_actType('MOVE');
- const getTreeData = async () => {
- let expandedKeys: (number | string)[] = [];
- const convertData = (data: Array<any>) => {
- data.forEach((item) => {
- item.title = item.name;
- item.key = item.menuId;
- if (!item.children || item.children.length == 0) {
- expandedKeys.push(item.menuId);
- convertData(item.children);
- const resp = await getMenuDirectory();
- if (resp) {
- let data = resp.list;
- convertData(data)
- setExpandedKeys(Array.from(new Set(expandedKeys)));
- set_treeData(data);
+ const resp = await getMenuDirectory();
+ let data = resp.list;
+ convertData(data);
+ setExpandedKeys(Array.from(new Set(expandedKeys)));
+ set_treeData(data);
+ console.log({ resp });
- getTreeData();
- <Radio.Group defaultValue={actType} buttonStyle="solid" onChange={(e)=>radioOnchange(e as unknown as React.ChangeEvent<HTMLInputElement>)}>
- <Radio.Button value="COPY">复制</Radio.Button>
- <Radio.Button value="MOVE">移动</Radio.Button>
- </Radio.Group>
- <Divider plain>请选择</Divider>
- expandedKeys.length > 0 && treeData.length > 0 && (
- <Tree
- // checkable
- showLine
- blockNode
- autoExpandParent={true}
- // onCheck={onCheck}
- defaultExpandAll
- // onExpand={onExpand}
- expandedKeys={expandedKeys}
- // autoExpandParent={autoExpandParent}
- // // onCheck={onCheck}
- // checkedKeys={checkedKeys}
- onSelect={onSelect}
- // selectedKeys={selectedKeys}
- treeData={treeData as any}
- {/* {getTreeNode(treeData)} */}
- </Tree>
+ getTreeData();
+ <Radio.Group defaultValue={actType} buttonStyle="solid" onChange={(e) => radioOnchange(e as unknown as React.ChangeEvent<HTMLInputElement>)}>
+ <Radio.Button value="COPY">复制</Radio.Button>
+ <Radio.Button value="MOVE">移动</Radio.Button>
+ </Radio.Group>
+ <Divider plain>请选择</Divider>
+ {expandedKeys.length > 0 && treeData.length > 0 && (
+ <Tree
+ // checkable
+ showLine
+ blockNode
+ autoExpandParent={true}
+ // onCheck={onCheck}
+ defaultExpandAll
+ // onExpand={onExpand}
+ expandedKeys={expandedKeys}
+ // autoExpandParent={autoExpandParent}
+ // // onCheck={onCheck}
+ // checkedKeys={checkedKeys}
+ onSelect={onSelect}
+ // selectedKeys={selectedKeys}
+ treeData={treeData as any}
+ {/* {getTreeNode(treeData)} */}
+ </Tree>
-export default TreeEditer
+export default TreeEditer;
@@ -10,7 +10,7 @@
import React, { Key, useEffect, useState } from 'react';
import KCTable from '@/components/kcTable';
import { Popconfirm } from 'antd';
-import { Input,Transfer, Tree } from 'antd';
+import { Input, Transfer, Tree } from 'antd';
import { getAllMenus, getAllMenusDataType, getHospAllMenus } from '@/service/menu';
import { ProColumns } from '@ant-design/pro-table';
import type { MenuItemDataType } from '@/service/menu';
@@ -29,128 +29,109 @@ export interface MenuEditerType {
value?: React.Key[] | React.Key[];
onChange?: (selectedRowKeys: React.Key[], selectedRows?: any[]) => {};
noAction?: boolean;
- hospId?:number|string;
+ hospId?: number | string;
-const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction = false,hospId }) => {
+const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction = false, hospId }) => {
const getData = async () => {
- if(hospId){
+ if (hospId) {
const resp = await getHospAllMenus(hospId);
const data = resp.allMenuVO;
const convertData = (data: Array<any>) => {
data.forEach((item) => {
- item.children = item.child;
- if (item.child) {
- convertData(item.child);
+ item.children = item.child;
+ if (item.child) {
+ convertData(item.child);
convertData(data);
setDataSource(data);
const resp = await getAllMenus();
const data = resp.list ? resp.list : [];
const [dataSource, setDataSource] = useState<any[]>([]);
const [targetKeys, setTargetKeys] = useState<string[]>([]);
- const [_selectedKeys,set__selectedKeys] = useState<string[]>([]);
+ const [_selectedKeys, set__selectedKeys] = useState<string[]>([]);
- const [sourceSelectedKeys,set_sourceSelectedKeys] = useState<string[]>([]);
+ const [sourceSelectedKeys, set_sourceSelectedKeys] = useState<string[]>([]);
const onTransFerChange = (keys: string[]) => {
let _keys = Array.from(new Set(keys));
setTargetKeys(_keys);
- onChange&&onChange(_keys)
+ onChange && onChange(_keys);
interface TreeTransferProps {
dataSource: MenuItemDataType[];
targetKeys: string[];
onChange: (targetKeys: string[], direction: TransferDirection, moveKeys: string[]) => void;
- const isChecked = (selectedKeys:(string|number)[], eventKeys: (string|number)[]) => {
+ const isChecked = (selectedKeys: (string | number)[], eventKeys: (string | number)[]) => {
// console.log({selectedKeys,eventKeys});
- const isIncludesFunc = (arr1:(string|number)[],arr2:(string|number)[])=>{
- if(arr2.length == 0){
- return true;
- return arr2.every((item)=>arr1.includes(item))
- return isIncludesFunc(selectedKeys,eventKeys)
+ const isIncludesFunc = (arr1: (string | number)[], arr2: (string | number)[]) => {
+ if (arr2.length == 0) {
+ return arr2.every((item) => arr1.includes(item));
+ return isIncludesFunc(selectedKeys, eventKeys);
const generateTree = (treeNodes: MenuItemDataType[] = [], checkedKeys: string[] = []): any[] => {
+ return treeNodes.map(({ children, menuId, name, ...props }) => ({
+ key: menuId,
+ title: name,
+ disabled: checkedKeys.includes(menuId as string),
+ children: generateTree(children, checkedKeys),
+ ...props,
- return treeNodes.map(({ children,menuId,name, ...props }) => ({
- key:menuId,
- title:name,
- disabled: checkedKeys.includes(menuId as string),
- children: generateTree(children, checkedKeys),
- ...props
- const onSelectChangeHandle = (_sourceSelectedKeys:Key[], targetSelectedKeys:Key[])=>{
- set_sourceSelectedKeys(_sourceSelectedKeys as string[]);
- // set_selectedKeysVal(sourceSelectedKeys as string[]);
- // setTargetKeys(targetSelectedKeys as string[]);
+ const onSelectChangeHandle = (_sourceSelectedKeys: Key[], targetSelectedKeys: Key[]) => {
+ set_sourceSelectedKeys(_sourceSelectedKeys as string[]);
+ // set_selectedKeysVal(sourceSelectedKeys as string[]);
+ // setTargetKeys(targetSelectedKeys as string[]);
const TreeTransfer = ({ dataSource, targetKeys, ...restProps }: TreeTransferProps) => {
const transferDataSource: MenuItemDataType[] = [];
function flatten(list: MenuItemDataType[] = []) {
- list.forEach(item => {
+ list.forEach((item) => {
transferDataSource.push(item as MenuItemDataType);
flatten(item.children);
flatten(dataSource);
<Transfer
{...restProps}
- listStyle={{width:100,height:500}}
+ listStyle={{ width: 100, height: 500 }}
targetKeys={targetKeys}
- rowKey={record => record.menuId}
+ rowKey={(record) => record.menuId}
dataSource={transferDataSource}
className="tree-transfer"
// onSelectChange={onSelectChangeHandle}
// selectedKeys={_selectedKeys}
- render={item => item.name!}
+ render={(item) => item.name!}
showSelectAll={true}
- {({ direction, onItemSelect, selectedKeys,onItemSelectAll }) => {
+ {({ direction, onItemSelect, selectedKeys, onItemSelectAll }) => {
if (direction === 'left') {
const checkedKeys = [...selectedKeys, ...targetKeys];
@@ -162,30 +143,26 @@ const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction =
height={460}
checkedKeys={checkedKeys}
treeData={generateTree(dataSource, targetKeys)}
- onCheck={(keys,{node,halfCheckedKeys,...rest}) => {
+ onCheck={(keys, { node, halfCheckedKeys, ...rest }) => {
// console.log({keys,node,rest});
// 差集
- let difference = (keys as Key[]).filter(v => !targetKeys.includes(v as string) );
- const map = (list:any, cb:any) => {
- return list.reduce((res:any, v:any) => {
- res.push(cb(v));
- if(Array.isArray(v.child)) res = res.concat(map(v.child, cb))
- return res;
+ let difference = (keys as Key[]).filter((v) => !targetKeys.includes(v as string));
+ const map = (list: any, cb: any) => {
+ return list.reduce((res: any, v: any) => {
+ res.push(cb(v));
+ if (Array.isArray(v.child)) res = res.concat(map(v.child, cb));
+ return res;
+ if (!node.checked) {
+ //选中
+ onItemSelectAll(difference as string[], true);
+ //取消勾选
+ const cancelKeys = map(node.children, (v: any) => v.key);
+ onItemSelectAll([node.key, ...cancelKeys, ...(halfCheckedKeys as Key[])] as string[], false);
- if(!node.checked){
- //选中
- onItemSelectAll(difference as string[],true);
- //取消勾选
- const cancelKeys = map(node.children,(v:any)=>v.key);
- onItemSelectAll([node.key,...cancelKeys,...halfCheckedKeys as Key[]] as string[],false)
onSelect={(keys, { node: { key } }) => {}}
@@ -195,10 +172,10 @@ const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction =
</Transfer>
setTargetKeys(value as string[]);
- },[value])
getData();
@@ -206,7 +183,7 @@ const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction =
<div className="MenuEditer">
- <TreeTransfer dataSource={dataSource} targetKeys={targetKeys} onChange={onTransFerChange} />
+ <TreeTransfer dataSource={dataSource} targetKeys={targetKeys} onChange={onTransFerChange} />
* @Date: 2022-01-19 14:53:37
- * @LastEditTime: 2022-07-07 09:20:34
+ * @LastEditTime: 2024-01-19 14:45:27
* @FilePath: /KC-MiddlePlatform/src/pages/platform/components/usersEditer/index.tsx
@@ -9,7 +9,7 @@
import React, { useEffect, useState } from 'react';
-import { Input,Transfer } from 'antd';
+import { Input, Transfer } from 'antd';
import { getUsers } from '@/service/user';
import type { EditUsersDataType } from '@/service/user';
@@ -22,19 +22,10 @@ export interface UserEditerType {
onChange?: (selectedRowKeys: React.Key[]) => {};
- total?:[]
+ total?: [];
-const UserEditer: React.FC<UserEditerType> = ({
- value = [],
- onChange,
- noAction = false,
- total = []
-}) => {
+const UserEditer: React.FC<UserEditerType> = ({ value = [], onChange, noAction = false, total = [] }) => {
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [keyword, setKeyword] = useState('');
@@ -42,12 +33,7 @@ const UserEditer: React.FC<UserEditerType> = ({
const [targetKeys, setTargetKeys] = useState<React.Key[]>([]);
//record: T, selected: boolean, selectedRows: T[], nativeEvent: Event
- const onSelectHandle = (
- record: EditUsersDataType,
- selected: boolean,
- selectedRows: EditUsersDataType[],
- nativeEvent: Event,
- ) => {
+ const onSelectHandle = (record: EditUsersDataType, selected: boolean, selectedRows: EditUsersDataType[], nativeEvent: Event) => {
// console.log({record,selected,selectedRows,nativeEvent});
if (selected) {
//保证每次选择能够保留之前选中的
@@ -58,68 +44,49 @@ const UserEditer: React.FC<UserEditerType> = ({
- const onChangeHandle = (
- selectedRowKeys: React.Key[],
- selectedRows: any[],
+ const onChangeHandle = (selectedRowKeys: React.Key[], selectedRows: any[]) => {
if (selectedRows.length == 0) {
//取消选择时
setSelectedKeys([]);
- const onSearchHandle = (
- e: React.ChangeEvent & { target: { value: string } },
+ const onSearchHandle = (e: React.ChangeEvent & { target: { value: string } }) => {
setKeyword(e.target.value);
- const filterOption = (inputValue: string, option: EditUsersDataType) =>
- option.name&&option.name.indexOf(inputValue) > -1;
+ const filterOption = (inputValue: string, option: EditUsersDataType) => option.name && option.name.indexOf(inputValue) > -1;
const handleChange = (newTargetKeys: string[]) => {
setTargetKeys(newTargetKeys);
- onChange&&onChange(newTargetKeys);
- const handleSearch = (dir: TransferDirection, value: string) => {
+ onChange && onChange(newTargetKeys);
+ const handleSearch = (dir: TransferDirection, value: string) => {};
onChange && onChange(selectedKeys);
}, [selectedKeys]);
- setTargetKeys(value);
- setData(total)
+ setTargetKeys(value);
+ setData(total);
<div className="UserEditer">
- <Transfer
- dataSource={data}
- showSearch
- pagination={{pageSize:20}}
- rowKey={record => `${record.id}`}
- showSelectAll={true}
- // filterOption={filterOption}
- targetKeys={targetKeys as string[]}
- onChange={handleChange}
- onSearch={handleSearch}
- render={item => item.name?item.name:''}
+ <Transfer
+ dataSource={data}
+ showSearch
+ pagination={{ pageSize: 20 }}
+ rowKey={(record) => `${record.id}`}
+ showSelectAll={true}
+ // filterOption={filterOption}
+ targetKeys={targetKeys as string[]}
+ onChange={handleChange}
+ onSearch={handleSearch}
+ render={(item) => (item.name ? `${item.name}(${item.account})` : '')}
{/* <div className="search">
<span className="label">搜索人员:</span>
@@ -8,8 +8,103 @@
-.kcmp-ant-pro-sider-light .kcmp-ant-menu-light {
+.kcmp-ant-pro-sider-light {
border-right-color: rgba(54, 61, 77, 0.1);
+ .kcmp-ant-menu-light {
+ .kcmp-ant-menu-submenu-inline {
+ .kcmp-ant-menu-submenu-title {
+ // padding-left: 8px !important;
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ &.kcmp-ant-menu-submenu-selected {
+ .kcmp-ant-menu-submenu-arrow {
+ color: #3376FE !important;
+ .kcmp-ant-menu-inline {
+ .kcmp-ant-menu-item {
+ a:hover {
+ color: rgba(0, 0, 0, 0.88);
+ &.kcmp-ant-menu-item-selected {
+ background-color: #F2F6FF !important;
+ color: #3376FE;
+ display: none !important;
+ color: rgba(0, 0, 0, 0.88) !important;
+ background-color:#f0f2f5;
+ &.kcmp-ant-pro-sider-link-menu {
+ //height: 24px !important;
+ .collapsedBtn {
+ bottom:0px;
+ z-index: 10;
+ width: 23px;
+ height: 23px;
+ &.kcmp-ant-menu-inline-collapsed {
+ // position: absolute;
+ // right:0px;
+ // bottom: 0px;
+ .kcmp-ant-menu-submenu-selected {
+ background-color:#F2F6FF;
.kcmp-ant-page-header {
@@ -20,8 +115,8 @@
.kcmp-ant-pro-page-container-children-content {
margin: 0;
margin-top: 16px;
- margin-left:16px;
- margin-right:12px;
+ margin-left: 16px;
+ margin-right: 12px;
@@ -2,7 +2,7 @@
* @Date: 2023-03-03 11:30:33
- * @LastEditTime: 2023-03-31 17:22:38
+ * @LastEditTime: 2023-06-09 10:57:54
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
* @Date: 2022-01-12 17:11:11
- * @LastEditTime: 2023-03-23 17:50:10
+ * @LastEditTime: 2024-01-19 10:35:31
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/userManage/modal.tsx
@@ -33,7 +33,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
const [dataSource, setDataSource] = useState<DataSourceType[]>([]);
- const [dirData,set_dirData] = useState<PlatformPubDirDataType[]>([]);
+ const [dirData, set_dirData] = useState<PlatformPubDirDataType[]>([]);
const columns: ProColumns<DataSourceType>[] = [
@@ -95,7 +95,6 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
const onFinishHandle = (data: any & AddUsersDataType) => {
if (tableAct == TableActType.ADD) {
dispatch &&
dispatch({
@@ -104,15 +103,20 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
- if (
- tableAct == TableActType.EDIT ||
- tableAct == TableActType.EDITMENU ||
- tableAct == TableActType.BINDACCOUNT
- ) {
+ if (tableAct == TableActType.EDIT || tableAct == TableActType.BINDACCOUNT) {
+ console.log({ data });
type: 'hospManageModel/postEditData',
- payload: data,
+ payload:
+ tableAct == TableActType.EDIT
+ ...data,
+ parentId: data.isHospital ? data.parentId.value : undefined,
+ parentName: data.isHospital ? data.parentId.label : '-',
+ : data,
return true;
@@ -125,34 +129,29 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
return '新增院区';
- if (tableAct == TableActType.EDITMENU) {
- return '绑定菜单';
if (tableAct == TableActType.BINDACCOUNT) {
return '院区报告设置';
- const setInitialValues = () => {
+ const setInitialValues: any = () => {
if (tableAct == TableActType.EDIT) {
...currentEdit,
+ parentId: currentEdit?.parentId,
+ parentName: currentEdit?.parentName,
isDataShare: currentEdit?.dataShare == '是' ? 1 : 0,
hospSign: randomString(16),
isDataShare: 0,
- hospitalLevel:setSelectorData('HOSPITAL_LEVEL').defaultvalue,
- hospitalType:setSelectorData('HOSPITAL_TYPE').defaultvalue,
- hospitalNature:setSelectorData('HOSPITAL_NATURE').defaultvalue
+ hospitalLevel: setSelectorData('HOSPITAL_LEVEL').defaultvalue,
+ hospitalType: setSelectorData('HOSPITAL_TYPE').defaultvalue,
+ hospitalNature: setSelectorData('HOSPITAL_NATURE').defaultvalue,
- return { ...currentEdit };
if (currentEdit?.reportId) {
return { ...currentEdit, reportId: parseInt(currentEdit.reportId) };
@@ -161,78 +160,65 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
const getDirecData = async (key?: string) => {
const data = await getPlatformDictionary();
if (data) {
set_dirData(data);
const setSelectorData = (key: string) => {
- let result = dirData.filter((t: any) => (t.code == key));
+ let result = dirData.filter((t: any) => t.code == key);
if (result.length > 0) {
let dataArr = result[0].dataVoList;
- let defaultValue = dataArr.filter(t=>t.defaultValue == 1);
+ let defaultValue = dataArr.filter((t) => t.defaultValue == 1);
- dataArr.sort((prev:any,next:any)=>{
+ dataArr.sort((prev: any, next: any) => {
return prev.sort - next.sort;
- defaultvalue:defaultValue[0]?defaultValue[0].value:'',
- list:dataArr.map(t=>({label:t.code,value:t.value,defaultValue:t.defaultValue}))
+ defaultvalue: defaultValue[0] ? defaultValue[0].value : '',
+ list: dataArr.map((t) => ({ label: t.name, value: t.code, defaultValue: t.defaultValue })),
- defaultvalue:'',
- list:[]
+ defaultvalue: '',
+ list: [],
//加装key字段
const fixedDataSource = currentEdit?.youshuUsers
? currentEdit.youshuUsers.map((t) => ({
- key: Number((Math.random() * 1000000).toFixed(0)),
+ ...t,
+ key: Number((Math.random() * 1000000).toFixed(0)),
+ }))
: [];
setDataSource(fixedDataSource);
}, [currentEdit]);
getDirecData();
<KCModal
visible={isShowModal}
onVisibleChange={onVisibleChangeHandle}
layout="horizontal"
- width={tableAct == TableActType.EDITMENU?800:800}
+ width={480}
initialValues={setInitialValues()}
title={setModalTitle()}
- labelCol={{
- span: 7,
+ labelCol={{
+ span: 5,
wrapperCol={{ span: 12 }}
- onFinish={async (data) =>
- onFinishHandle(tableAct == TableActType.BINDACCOUNT ? { ...data, dataSource } : data)
+ onFinish={async (data) => onFinishHandle(tableAct == TableActType.BINDACCOUNT ? { ...data, dataSource } : data)}
- {tableAct == TableActType.EDITMENU && (
- <Form.Item name="bindMenuIds">
- <MenuEditer />
- </Form.Item>
- )}
- {tableAct != TableActType.EDITMENU && tableAct != TableActType.BINDACCOUNT && (
+ {tableAct != TableActType.BINDACCOUNT && (
<ProFormText
width="md"
@@ -274,11 +260,14 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
<KCProSelect
label="选择主院"
- name="mainHospId"
+ name="parentId"
+ fieldProps={{
+ labelInValue: true,
request={async () => {
- const hospList = await getHospList();
+ const hospList: any[] = await getHospList();
if (hospList) {
- return hospList.map((t) => ({
+ return hospList.map((t: any) => ({
label: t.name,
value: t.id,
}));
@@ -301,8 +290,9 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
name="hospitalLevel"
- return setSelectorData('HOSPITAL_LEVEL').list;
+ return setSelectorData('HOSPITAL_LEVEL').list;
+ fieldProps={{ showSearch: true }}
rules={[
required: true,
@@ -317,6 +307,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
return setSelectorData('HOSPITAL_TYPE').list;
@@ -331,6 +322,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
return setSelectorData('HOSPITAL_NATURE').list;
@@ -340,14 +332,23 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
<ProFormText width="md" name="hospSign" label="医院标识" disabled />
- <ProFormText width="md" name="hospAbbreviation" label="简称" placeholder="请输入"
+ <ProFormText
+ width="md"
+ name="hospAbbreviation"
+ label="简称"
+ placeholder="请输入"
- ]} />
- <ProFormText width="md" name="systemName" label="系统名称" placeholder="请输入"
+ ]}
+ name="systemName"
+ label="系统名称"
@@ -369,6 +370,20 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
]}
+ <ProFormRadio.Group
+ name="loadType"
+ label="登陆模式"
+ options={[
+ label: '简易',
+ value: 1,
+ label: '普通',
+ value: 0,
{tableAct == TableActType.BINDACCOUNT && (
@@ -1,8 +1,8 @@
* @Date: 2022-01-12 10:12:55
- * @LastEditTime: 2022-03-03 09:05:55
- * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2023-08-18 21:37:40
+ * @LastEditors: code4eat awesomedema@gmail.com
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/userManage/model.ts
@@ -31,7 +31,7 @@ enum TableActType {
BINDACCOUNT, //绑定有数账号
-type CurrentSelectedData = TableListItem & GetHospYoushuAccountsType;
+type CurrentSelectedData = TableListItem & GetHospYoushuAccountsType&{[key:string]:any};
export interface hospManageModelState {
name: string;
tableAct: TableActType;
@@ -73,9 +73,6 @@ const hospManageModel: hospManageModelType = {
effects: {
*query({ payload }, { call, put }) {},
*postAddData({ payload }, { call, put }) {
yield addHosp({ mainHospId: 0, ...payload });
yield put({
@@ -9,13 +9,34 @@
- font-family: SourceHanSansCN-Medium, SourceHanSansCN;
color: #17181A;
line-height:16px;
.btnGroup {
+ .clearBtn {
+ width: 112px;
+ line-height: 23px;
+ &.disabled {
+ cursor: not-allowed;
+ color: #65676a;
+ background-color: #f5f5f5;
.cancel {
@@ -27,7 +48,6 @@
border: 1px solid #DAE2F2;
@@ -44,7 +64,6 @@
color: #fff;
@@ -101,7 +120,6 @@
color: #FFF;
@@ -116,7 +134,6 @@
background: #F0FCFC;
margin-top: 12px;
margin-bottom: 15px;
@@ -124,7 +141,6 @@
&>span {
color: #00B3B3;
@@ -212,7 +228,6 @@
color: #FFFFFF;
* @Date: 2022-01-13 11:10:58
- * @LastEditTime: 2022-01-13 17:38:05
+ * @LastEditTime: 2023-08-18 21:36:41
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/userManage/typings.d.ts
@@ -17,6 +17,8 @@ export type TableListItem = {
updateTime: string;
systemName: string;
dataShare: number;
+ parentId:string;
+ parentName:string;
// export enum TableActType {
@@ -0,0 +1,494 @@
+/*
+ * @Author: code4eat awesomedema@gmail.com
+ * @Date: 2023-03-03 11:30:33
+ * @LastEditTime: 2023-09-28 11:17:13
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/index.tsx
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+import { KCInput } from '@/components/KCInput';
+import KCTable from '@/components/kcTable';
+import { ModalForm, ProFormDependency, ProFormInstance, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form'
+import { ProColumns } from '@ant-design/pro-table';
+import { Input, message, Modal, Popconfirm, Switch, TreeProps } from 'antd';
+import React, { Key, useEffect, useRef, useState } from 'react'
+import { addData, delData, dicOpenStatHandle, editData, getData, getTreeData } from './service';
+import './style.less';
+import { DataNode } from 'antd/lib/tree';
+import expandedIcon from '../../../../../public/images/treenode_open.png';
+import closeIcon from '../../../../../public/images/treenode_collapse.png';
+import DirectoryTree from 'antd/es/tree/DirectoryTree';
+import { getDeepestTreeData } from '@/utils';
+import { getPubDicData } from '@/service/public';
+import { getCurrentHospAllDepartments, getCurrentHospAllEmps } from '@/service/hospList';
+const SearchIcon = createFromIconfontCN({
+ scriptUrl: '//at.alicdn.com/t/c/font_1927152_g1njmm1kh7b.js',
+export default function PubDicTypeMana() {
+ const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
+ const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
+ const [reload, set_reload] = useState(false);
+ const [currentEdit, set_currentEdit] = useState<any>(undefined);
+ const [treeData, set_treeData] = useState<any[]>([]);
+ const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();
+ const [searchValue, setSearchValue] = useState('');
+ const [autoExpandParent, setAutoExpandParent] = useState(true);
+ const [defaultSelectedKeys,set_defaultSelectedKeys] = useState<Key[]>([]);
+ const columns: ProColumns[] = [
+ title: '参数等级',
+ dataIndex: 'levelName',
+ title: '作用对象',
+ dataIndex: 'targetName',
+ title: '参数值',
+ dataIndex: 'value',
+ title: '启用',
+ dataIndex: 'status',
+ hideInTable:currentSelectedTreeNode?.status != 1,
+ renderText(val, record, index, action) {
+ return <Switch size='small' checked={val? true : false} onChange={(bool) => chnageDicOpenStatHandle(bool, record)} />
+ title: '操作',
+ key: 'option',
+ width: 120,
+ valueType: 'option',
+ render: (_: any, record: any) => {
+ return [
+ <UpDataActBtn key={'act'} record={record} type='EDIT' />,
+ <Popconfirm
+ title="是否确认删除?"
+ key="del"
+ onConfirm={() => delTableData(record)}
+ <a>删除</a>
+ </Popconfirm>
+ ]
+ const chnageDicOpenStatHandle = async (bool: boolean, record: any) => {
+ const resp = await dicOpenStatHandle({ id: record.id, status: bool ? '1' : '0' });
+ set_reload(true);
+ const getTableData = async (params: any) => {
+ const resp = await getData({ ...params, parameterCode: currentSelectedTreeNode.code });
+ set_reload(false);
+ data: resp.list,
+ success: true,
+ total: resp.totalCount,
+ return []
+ const delTableData = async (record: any) => {
+ const resp = await delData(record.id);
+ // message.success('操作成功!');
+ const updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
+ if (type == 'ADD') {
+ const resp = await addData({
+ code:currentSelectedTreeNode.code,
+ level:formVal.level,
+ systemId:currentSelectedTreeNode.systemId,
+ targetCode:formVal.target.value,
+ targetName:formVal.target.label,
+ value:formVal.value
+ if (type == 'EDIT') {
+ const { id,status } = currentEdit;
+ const resp = await editData({
+ id:id,
+ value:formVal.value,
+ status:status,
+ const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
+ const formRef = useRef<ProFormInstance>();
+ <ModalForm
+ title={`${type == 'EDIT' ? '编辑' : '新增'}参数(${currentSelectedTreeNode&¤tSelectedTreeNode.name})`}
+ width={352}
+ formRef={formRef}
+ initialValues={type == 'EDIT' ? { ...record,level:`${record.level}`,target:{label:record.targetName,value:record.targetCode} } : {}}
+ trigger={
+ type == 'EDIT' ? <a key="edit" onClick={(e) =>{e.stopPropagation();set_currentEdit(record)} }>编辑</a> : <span className='add'>新增</span>
+ onFinish={(val) => {
+ return updateTable(val, type);
+ <ProFormSelect
+ name="level"
+ label="参数等级:"
+ placeholder="请选择院区"
+ request={async () => {
+ const resp = await getPubDicData('PARAMS_LEVEL');
+ const data: any = resp.dataVoList?.map((a: any) => ({
+ label: a.name,
+ value: a.code
+ return data;
+ onChange(value, option) {
+ formRef.current?.setFieldValue('target',undefined);
+ rules={[{ required: true, message: '参数等级不能为空!' }]}
+ <ProFormDependency name={['level']}>
+ ({ level }) => {
+ name="target"
+ label="作用对象:"
+ placeholder="请选择"
+ params={level}
+ rules={[{ required: true, message: '作用对象不能为空!' }]}
+ request={ async () => {
+ if (level == '1') {
+ const currentSelectedHop = localStorage.getItem('currentSelectedSubHop');
+ if (currentSelectedHop) {
+ const { id, name } = JSON.parse(currentSelectedHop);
+ return [{
+ value: id,
+ label: name
+ }]
+ if (level == '2') {
+ const resp = await getCurrentHospAllDepartments();
+ const data: any = resp.map((a: any) => ({
+ value: a.id
+ if (level == '3') {
+ const resp = await getCurrentHospAllEmps();
+ labelInValue:true
+ )
+ </ProFormDependency>
+ <ProFormTextArea
+ name="value"
+ label="参数值:"
+ rules={[{ required: true, message: '参数值不能为空!' }]}
+ </ModalForm>
+ const tableDataSearchHandle = (paramName: string) => {
+ set_tableDataFilterParams({
+ ...tableDataFilterParams,
+ [`${paramName}`]: tableDataSearchKeywords
+ const getTreeReqFunc = async (name?: string) => {
+ const resp = await getTreeData();
+ const treeData = resp.map((a: any) => ({
+ ...a,
+ name: a.systemName,
+ id:Math.random(),
+ children: a.parameters
+ set_treeData(treeData);
+ const dataList: any[] = [];
+ const getParentKey = (key: React.Key, tree: any[]): React.Key => {
+ let parentKey: React.Key;
+ for (let i = 0; i < tree.length; i++) {
+ const node = tree[i];
+ if (node.children.some((item: { id: React.Key; }) => item.id === key)) {
+ parentKey = node.id;
+ } else if (getParentKey(key, node.children)) {
+ parentKey = getParentKey(key, node.children);
+ return parentKey!;
+ const generateList = (data: any[]) => {
+ for (let i = 0; i < data.length; i++) {
+ const node = data[i];
+ const { id, name } = node;
+ dataList.push({ id, name: name });
+ generateList(node.children);
+ generateList(treeData as any);
+ const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ const { value } = e.target;
+ const newExpandedKeys = dataList
+ .map((item) => {
+ if (item.name.indexOf(value) > -1) {
+ return getParentKey(item.id, treeData);
+ return null;
+ const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);
+ setExpandedKeys(newExpandedKeys as React.Key[]);
+ setSearchValue(value);
+ setAutoExpandParent(true);
+ const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
+ //console.log('selected', selectedKeys, info);
+ const { node } = info;
+ if (!node.children) {
+ set_currentSelectedTreeNode(node);
+ const onExpand = (newExpandedKeys: React.Key[]) => {
+ setExpandedKeys(newExpandedKeys);
+ setAutoExpandParent(false);
+ if (currentSelectedTreeNode) {
+ set_tableDataFilterParams({ ...tableDataFilterParams, systemId: currentSelectedTreeNode.code });
+ }, [currentSelectedTreeNode]);
+ //初始化左侧树结构数据后
+ if (treeData?.length > 0) {
+ if (treeData[0].children && treeData[0].children.length > 0) {
+ const [node, nodeParent] = getDeepestTreeData(treeData[0], 'children');
+ setExpandedKeys([nodeParent.id]);
+ set_defaultSelectedKeys(node.id);
+ console.log({node,treeData});
+ }, [treeData]);
+ getTreeReqFunc();
+ <div className='PubDicTypeMana'>
+ <div className='left'>
+ <div className='search'>
+ <Input
+ className='searchInput'
+ size='small'
+ allowClear
+ style={{ marginBottom: 16 }}
+ onChange={onTreeSearchKeyChange}
+ suffix={
+ <SearchIcon type='iconsousuo' />
+ treeData && treeData.length > 0 && (
+ <DirectoryTree
+ fieldNames={{ title: 'name', key: 'id' }}
+ rootStyle={{ height: '100%', paddingBottom: 50, overflowY: 'scroll', overflowX: 'hidden' }}
+ onExpand={onExpand}
+ autoExpandParent={autoExpandParent}
+ selectedKeys={currentSelectedTreeNode ? [currentSelectedTreeNode.id] : []}
+ blockNode={true}
+ icon={() => null}
+ titleRender={
+ (nodeData: any) => {
+ const strTitle = nodeData.name as string;
+ const index = strTitle.indexOf(searchValue);
+ const beforeStr = strTitle.substring(0, index);
+ const afterStr = strTitle.slice(index + searchValue.length);
+ const title =
+ index > -1 ? (
+ <span>
+ {beforeStr}
+ <span className="site-tree-search-value" style={{ color: 'red', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{searchValue}</span>
+ {afterStr}
+ ) : (
+ <span className='strTitle'>{strTitle}</span>
+ return <div style={{
+ display: 'flex', flexDirection: 'row',
+ width: '100%',
+ justifyContent: 'flex-start', alignItems: 'center', height: 32,
+ borderRadius: '4px',
+ overflow: 'hidden',
+ color: '#17181A',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap'
+ }}>{title}</div>
+ defaultSelectedKeys={defaultSelectedKeys}
+ treeData={treeData as unknown as DataNode[]}
+ // treeData={treeDataNew}
+ switcherIcon={(props: any) => {
+ const { expanded } = props;
+ //return <button className='site-table-row-expand-icon site-table-row-expand-icon-expanded'></button>
+ return !expanded ? <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} /> : <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
+ <div className='right'>
+ <div className='rightTitle'>{currentSelectedTreeNode&¤tSelectedTreeNode.name}</div>
+ <div className='descr'>{`默认值:${currentSelectedTreeNode?currentSelectedTreeNode.value:''} 丨 参数描述:${currentSelectedTreeNode?currentSelectedTreeNode.description:''}`}</div>
+ <div className='toolBar'>
+ <div className='filter'>
+ <div className='filterItem'>
+ <span className='label'>检索:</span>
+ <KCInput placeholder={'请输入名称'} style={{ width: 160 }} search allowClear
+ onChange={(e) => {
+ set_tableDataSearchKeywords(e.target.value);
+ if (e.target.value.length == 0) {
+ targetName: ''
+ onSearch={() => tableDataSearchHandle('targetName')}
+ <div className='btnGroup'>
+ {currentSelectedTreeNode?.status == 1&&<UpDataActBtn record type='ADD' />}
+ <div style={{ marginTop: 16 }}>
+ {currentSelectedTreeNode && <KCTable columns={columns as ProColumns[]} reload={reload} rowKey='id' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />}
@@ -0,0 +1,107 @@
+ * @Date: 2023-03-03 16:31:27
+ * @LastEditTime: 2023-09-14 17:41:10
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
+import { request } from 'umi';
+//获取table列表数据
+export type HospParamsItemType = {
+ dictId:string;
+ dictName:string;
+ dictType:string;
+ hospId:string;
+ hospName:string;
+ remark:string;
+ status:string
+export const getData = (params?:any) => {
+ return request<{list:HospParamsItemType[],totalCount:number}>('/centerSys/parameter/getHospParameterList', {
+ method: 'GET',
+ params:{...params}
+//新增表格数据
+export type AddTableDataType = {
+ code:string,
+ level:string,
+ targetCode:string,
+ targetName:string,
+ value:string,
+ systemId:string;
+export const addData = (data:AddTableDataType) => {
+ return request('/centerSys/parameter/addHospParameter', {
+ method: 'POST',
+ data
+//获取左侧系统数据
+export const getTreeData = () => {
+ return request('/centerSys/parameter/getSystemParameterList', {
+//编辑表格数据
+export type EditTableDataType = {
+ id:number,
+ status:string,
+export const editData = (data:EditTableDataType) => {
+ return request('/centerSys/parameter/editHospParameter', {
+//删除表格操作
+export const delData = (id:string) => {
+ return request('/centerSys/parameter/deleteHospParameter', {
+ params:{id}
+//字典类型开放操作
+export const dicOpenStatHandle = (data:{id:string;status:string}) => {
+ return request('/centerSys/parameter/editStatus', {
+ params:{...data}
@@ -0,0 +1,138 @@
+.PubDicTypeMana {
+ width: 220px;
+ margin-right: 16px;
+ background: #FFFFFF;
+ .searchInput {
+ border: 1px solid #CFD7E6;
+ .wrap {
+ height: calc(100% - 55px);
+ .kcmp-ant-tree.kcmp-ant-tree-directory .kcmp-ant-tree-treenode {
+ //style={{display:'inline-flex',justifyContent:'center',alignItems:'center',width:16,height:16,background:'#fff',borderRadius:4,border:'1px solid #DAE2F2',marginLeft:4,position:'relative',top:2}}
+ .copy {
+ background: #F0F2F5;
+ display: inline-flex;
+ margin-left: 4px;
+ top: 2px;
+ &::before {
+ .kcmp-ant-tree.kcmp-ant-tree-directory .kcmp-ant-tree-treenode-selected {
+ .kcmp-ant-tree.kcmp-ant-tree-directory .kcmp-ant-tree-treenode .kcmp-ant-tree-node-content-wrapper.kcmp-ant-tree-node-selected {
+ width: calc(100% - 236px);
+ .rightTitle {
+ line-height: 16px;
+ .descr {
+ color: #515866;
+ .toolBar {
+ .filter {
+ .filterItem {
+ .add {
+ padding: 0 14px;
@@ -0,0 +1,219 @@
+ * @LastEditTime: 2023-12-04 19:41:52
+import { getAllHosp } from '@/service/hospList';
+import { getUserRelaSeletData } from '@/service/user';
+import { ModalForm, ProFormCascader, ProFormDigit, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
+import { Popconfirm } from 'antd';
+import { useEffect, useState } from 'react';
+import { getSysLists } from '../paramsMana/service';
+import { addData, delData, editData, getData } from './service';
+import { findParents, renameChildListToChildren, searchTreeAndKeepStructure } from '@/utils';
+export default function KcClassification() {
+ const [tableData, set_tableData] = useState<any[]>([]);
+ const [dataSource, set_dataSource] = useState<any[]>([]);
+ const columns = [
+ title: '分类名称',
+ dataIndex: 'name',
+ title: '分类代码',
+ dataIndex: 'code',
+ title: '序号',
+ dataIndex: 'sort',
+ title: '说明',
+ dataIndex: 'description',
+ <UpDataActBtn key={'act'} record={record} type="EDIT" />,
+ <Popconfirm title="是否确认删除?" key="del" onConfirm={() => delTableData(record)}>
+ </Popconfirm>,
+ <UpDataActBtn key={'act2'} record={record} type="ADDCHILD" />,
+ const getTableData = async () => {
+ const resp = await getData();
+ const data = renameChildListToChildren(resp, 'childList');
+ set_tableData(data);
+ set_dataSource(data);
+ const updateTable = async (formVal: any, type: 'EDIT' | 'ADD' | 'ADDCHILD') => {
+ // const parents = findParents(tableData, 'id', formVal.id);
+ // console.log({formVal});
+ const result = {
+ code: formVal.code,
+ name: formVal.name,
+ value: '',
+ sort: formVal.sort,
+ description: formVal.description,
+ ...result,
+ parentCode: undefined,
+ codePath: formVal.code,
+ levelName: formVal.name,
+ if (type == 'ADDCHILD') {
+ parentCode: formVal.parentCode,
+ codePath: `${formVal.codePath},${formVal.code}`,
+ levelName: `${formVal.levelName}/${formVal.name}`,
+ // const parents = findParents(tableData,'id',formVal.id);
+ // console.log({parents});
+ id: formVal.id,
+ const UpDataActBtn = ({ record, type }: { record: any; type: 'EDIT' | 'ADD' | 'ADDCHILD' }) => {
+ title={`${type == 'EDIT' ? '编辑' : type == 'ADDCHILD' ? '添加' : '新增'}康程分类`}
+ width={350}
+ initialValues={
+ type == 'EDIT'
+ ...record,
+ : {}
+ trigger={type == 'EDIT' ? <a key="edit">编辑</a> : <a className="add">{type == 'ADDCHILD' ? '添加' : '新增'}</a>}
+ return updateTable(type == 'EDIT' ? { ...val, id: record.id } : type == 'ADDCHILD' ? { ...record, ...val, parentCode: record.code } : { ...val }, type);
+ colProps={{ span: 24 }}
+ grid
+ <ProFormText name="name" label="分类名称:" placeholder="请输入" rules={[{ required: true, message: '名称不能为空!' }]} />
+ <ProFormText name="code" label="分类代码:" placeholder="请输入" rules={[{ required: true, message: '代码不能为空!' }]} />
+ <ProFormDigit name="sort" label="序号:" placeholder="请输入" rules={[{ required: true, message: '序号不能为空!' }]} />
+ <ProFormTextArea colProps={{ span: 24 }} name="description" label="说明:" placeholder="请输入" />
+ [`${paramName}`]: tableDataSearchKeywords,
+ if (reload) {
+ getTableData();
+ }, [reload]);
+ if (tableDataFilterParams) {
+ const { name } = tableDataFilterParams;
+ const result = searchTreeAndKeepStructure(dataSource, 'name', name);
+ set_tableData([...result]);
+ set_tableData(dataSource);
+ }, [tableDataFilterParams]);
+ <div className="KcClassification">
+ <div className="toolBar">
+ <div className="filter">
+ <div className="filterItem">
+ <span className="label">分类名称:</span>
+ <KCInput
+ placeholder={'请输入'}
+ style={{ width: 160 }}
+ search
+ name: '',
+ onSearch={() => tableDataSearchHandle('name')}
+ <UpDataActBtn record type="ADD" />
+ <KCTable scroll={{ y: `calc(100vh - 250px)` }} pagination={false} columns={columns as ProColumns[]} rowKey="id" newVer dataSource={tableData} />
@@ -0,0 +1,75 @@
+ * @LastEditTime: 2023-11-07 20:59:54
+export type TableDataType = {
+ hospId: string;
+ code: string;
+ value: string;
+ sort: number;
+ parentCode: string;
+ codePath: string;
+ levelName: string;
+ description: string;
+ childList: TableDataType[];
+export const getData = (params?: any) => {
+ return request<TableDataType[]>('/centerSys/kcClass/list', {
+ params: { ...params },
+ parentCode?: string;
+export const addData = (data: AddTableDataType) => {
+ return request('/centerSys/kcClass/add', {
+ data,
+export type EditableDataType = {
+export const editData = (data: EditableDataType) => {
+ return request('/centerSys/kcClass/edit', {
+export const delData = (id: string) => {
+ return request('/centerSys/kcClass/delete', {
+ params: { id },
@@ -0,0 +1,42 @@
+.KcClassification {
- * @LastEditTime: 2022-07-21 16:56:55
+ * @LastEditTime: 2023-08-31 10:57:48
@@ -12,7 +12,7 @@ import KCModal from '@/components/KCModal';
import KCProSelect from '@/components/KCProSelect';
import { menuManageModelState, Dispatch } from 'umi';
-import { Form } from 'antd'
+import { Form } from 'antd';
import { ProFormText, ProFormDependency, ProFormDigit, ProFormRadio, ProFormTextArea } from '@ant-design/pro-form';
import type { AddUsersDataType } from '@/service/user';
@@ -28,21 +28,14 @@ export enum TableActType { //表格操作类型枚举
DEL,
EDIT,
SET,
- MOVEANDCOPY
+ MOVEANDCOPY,
interface ActModalProps extends menuManageModelState {
dispatch: Dispatch | undefined;
-const ActModal: React.FC<ActModalProps> = ({
- dispatch,
- isShowModal,
- tableAct,
- currentEdit,
- parentId,
- record,
+const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, currentEdit, parentId, record }) => {
const onVisibleChangeHandle = (bool: boolean) => {
// console.log({bool});
if (!bool) {
@@ -90,8 +83,6 @@ const ActModal: React.FC<ActModalProps> = ({
const menuTypeOptionFiler = () => {
if (parentId == '0') {
//顶级目录
return MenuTypes.filter((t) => t.label == '中心层');
@@ -104,7 +95,7 @@ const ActModal: React.FC<ActModalProps> = ({
if (record?.type == 5) {
//体系
- return MenuTypes.filter((t) => (t.label == '系统' || t.label == '菜单'));
+ return MenuTypes.filter((t) => t.label == '系统' || t.label == '菜单');
if (record?.type == 3) {
@@ -127,7 +118,7 @@ const ActModal: React.FC<ActModalProps> = ({
if (key == TableActType.EDIT) return '编辑菜单';
if (key == TableActType.SET) return '设置首页';
if (key == TableActType.MOVEANDCOPY) return '复制/移动';
@@ -139,8 +130,10 @@ const ActModal: React.FC<ActModalProps> = ({
tableAct == TableActType.EDIT
? { ...currentEdit }
: {
- hospSign: randomString(16), isDataShare: 0, isHomepage: 0,
+ hospSign: randomString(16),
+ isDataShare: 0,
+ isHomepage: 0,
// title={tableAct == TableActType.EDIT ? '编辑菜单' : tableAct == TableActType.SET ? '设为首页' : '新增菜单'}
title={setModalFormTitle(tableAct)}
@@ -150,219 +143,205 @@ const ActModal: React.FC<ActModalProps> = ({
onFinish={async (data) => onFinishHandle(data)}
- tableAct == TableActType.SET && (
- <>
- <ProFormText
- width="md"
- name="menuName"
- label="首页名称"
- placeholder="请输入"
- rules={[
- required: false,
- message: '请输入名称(可选)',
- ]}
- </>
- tableAct == TableActType.MOVEANDCOPY && (
- <Form.Item name='treeEditer'>
- <TreeEditer />
- (tableAct == TableActType.ADD || tableAct == TableActType.EDIT) && (
- name="name"
- label="名称"
- required: true,
- message: '请输入名称!',
- <KCProSelect
- label="类型"
- name="type"
- options={menuTypeOptionFiler()}
- message: '请选择!',
- name="url"
- label="URL"
- message: '请输入!',
- <ProFormDependency name={['type', 'contentType']}>
+ {tableAct == TableActType.SET && (
+ <>
+ name="menuName"
+ label="首页名称"
+ rules={[
- ({ type, contentType }) => {
- if (type == 1 && contentType != 4) {
- name="path"
- label="PATH"
- initialValue={tableAct == TableActType.ADD ? '/platform' : ''}
- </ProFormDependency>
- <ProFormDigit
- label="排序号"
- name="orderNum"
- min={0}
- max={1000}
- fieldProps={{ precision: 0 }}
- <ProFormText width="md" name="icon" label="icon" placeholder="请输入" />
- <ProFormDependency name={['type']}>
- {({ type }) => {
- type == 1 && (
- //类型时菜单时
- label="内容类型"
- name="contentType"
- initialValue={0}
- options={[
- label: '一般',
- value: 0, //普通页面,默认值
- label: '报告',
- value: 1,
- label: '大屏',
- value: 2,
- label: '填报',
- value: 3,
- label: '空白',
- value: 4,
- <ProFormRadio.Group
- name="isHomepage"
- label="是否为首页"
- label: '是',
- label: '否',
- value: 0,
+ required: false,
+ message: '请输入名称(可选)',
+ </>
+ {tableAct == TableActType.MOVEANDCOPY && (
+ <Form.Item name="treeEditer">
+ <TreeEditer />
+ </Form.Item>
+ {(tableAct == TableActType.ADD || tableAct == TableActType.EDIT) && (
+ name="name"
+ label="名称"
+ required: true,
+ message: '请输入名称!',
+ <KCProSelect
+ label="类型"
+ name="type"
+ options={menuTypeOptionFiler()}
+ message: '请选择!',
+ name="url"
+ label="URL"
+ message: '请输入!',
- <ProFormDependency name={['contentType']}>
- {({ contentType }) => {
- contentType &&
- contentType != 0 && contentType != 4 && (
- //页面内容为非一般时,填写对应有数Id
- label="报告Id"
- name="reportId"
- min={1}
- message: '请填写id!',
+ <ProFormDependency name={['type', 'contentType']}>
+ {({ type, contentType }) => {
+ if (type == 1 && contentType != 4) {
+ name="path"
+ label="PATH"
+ initialValue={tableAct == TableActType.ADD ? '/platform' : ''}
- ({ contentType }) => {
- if (contentType == 4) {
- <ProFormTextArea
- name="description"
- label="空白页描述"
- fieldProps={{}}
+ <ProFormDigit label="排序号" name="orderNum" min={0} width="md" max={1000} fieldProps={{ precision: 0 }} />
+ <ProFormText width="md" name="icon" label="icon" placeholder="请输入" />
+ <ProFormDependency name={['type']}>
+ {({ type }) => {
+ type == 1 && (
+ //类型时菜单时
+ label="内容类型"
+ name="contentType"
+ initialValue={0}
+ label: '一般',
+ value: 0, //普通页面,默认值
+ label: '报告',
+ label: '大屏',
+ value: 2,
+ label: '填报',
+ value: 3,
+ label: '空白',
+ value: 4,
+ label: '静态',
+ value: 5,
+ label: '外部系统嵌入',
+ value: 6,
+ name="isHomepage"
+ label="是否为首页"
+ label: '是',
+ label: '否',
+ <ProFormDependency name={['contentType']}>
+ {({ contentType }) => {
+ contentType &&
+ contentType != 0 &&
+ contentType != 4 &&
+ contentType != 6 && (
+ //页面内容为非一般时,填写对应有数Id
+ <ProFormDigit
+ label="报告Id"
+ name="reportId"
+ min={1}
+ fieldProps={{ precision: 0 }}
+ message: '请填写id!',
+ if (contentType == 4) {
+ return <ProFormTextArea name="description" label="空白页描述" placeholder="请输入" fieldProps={{}} />;
</KCModal>
- * @LastEditTime: 2023-03-23 17:54:17
+ * @LastEditTime: 2023-09-28 11:20:09
@@ -143,7 +143,7 @@ export default function PubDicTypeMana() {
defaultvalue: defaultValue[0] ? defaultValue[0].value : '',
- list: dataArr.map((t: any) => ({ label: t.value, value: t.code }))
+ list: dataArr.map((t: any) => ({ label: t.name, value: t.code }))
@@ -183,7 +183,7 @@ export default function PubDicTypeMana() {
<ModalForm
title={`${type == 'EDIT' ? '编辑' : '新增'}消息模板`}
- width={700}
+ width={730}
initialValues={type == 'EDIT' ? {
...record,
systemId:record.systemPath?record.systemPath.split(','):[]
@@ -307,7 +307,7 @@ export default function PubDicTypeMana() {
},[])
- <div className='PubDicTypeMana'>
+ <div className='NotificationTemplate'>
<div className='toolBar'>
<div className='filter'>
<div className='filterItem'>
@@ -389,7 +389,7 @@ export default function PubDicTypeMana() {
<div style={{ marginTop: 16 }}>
- <KCTable columns={columns as ProColumns[]} reload={reload} rowKey='id' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />
+ <KCTable scroll={{y:`calc(100vh - 250px)`}} columns={columns as ProColumns[]} reload={reload} rowKey='id' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />
@@ -1,4 +1,4 @@
-.PubDicTypeMana {
+.NotificationTemplate {
- * @LastEditTime: 2023-03-09 17:15:03
+ * @LastEditTime: 2023-09-15 17:49:44
@@ -14,13 +14,22 @@ import KCTable from '@/components/kcTable';
import { getAllHosp } from '@/service/hospList';
import { ModalForm, ProFormCascader, ProFormDigit, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea, ProFormTreeSelect } from '@ant-design/pro-form'
-import { message, Popconfirm } from 'antd';
-import React, { useState } from 'react'
-import { addData, delData, editData, getData, getSysLists } from './service';
+import { Input, message, Popconfirm, Switch, TreeProps } from 'antd';
+import React, { Key, useEffect, useState } from 'react'
+import { addData, delData, editData, getParamsManaTableData, getSysLists } from './service';
+import { DataNode } from 'antd/es/tree';
export default function ParamsMana() {
@@ -30,9 +39,22 @@ export default function ParamsMana() {
const [currentEdit, set_currentEdit] = useState<any>(undefined);
+ const [defaultSelectedKeys, set_defaultSelectedKeys] = useState<Key[]>([]); //默认选中的左侧系统
- const columns = [
+ title: '参数代码',
title: '参数名称',
dataIndex: 'name',
@@ -41,28 +63,29 @@ export default function ParamsMana() {
title: '参数说明',
dataIndex: 'description',
+ ellipsis: true
title: '参数值',
dataIndex: 'value',
- title: '院区',
- dataIndex: 'hospName',
+ // title: '院区',
+ // dataIndex: 'hospName',
- title: '系统',
- dataIndex: 'systemName',
+ // title: '系统',
+ // dataIndex: 'systemName',
- title: '启用',
+ title: '开放',
dataIndex: 'status',
- render: (_: any, record: any) => {
- console.log({record});
- return <span style={{ color: record.status == 1?'#00BF8F':'red' }}>{record.status == 1 ? '启用' : '禁用'}</span>
+ return <Switch size='small' checked={val ? true : false} onChange={(bool) => changeOpenStatHandle(bool, record)} />
title: '操作',
@@ -84,11 +107,18 @@ export default function ParamsMana() {
+ const changeOpenStatHandle = async (bool: boolean, record: any) => {
+ const resp = await editData({ ...record, status: bool ? '1' : '0' })
const getTableData = async (params: any) => {
- const resp = await getData(params);
+ const resp = await getParamsManaTableData(params);
set_reload(false);
@@ -111,15 +141,15 @@ export default function ParamsMana() {
const updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
- const {systemId} = formVal;
+ const { systemId } = formVal;
if (type == 'ADD') {
- const resp = await addData({...formVal,systemId:systemId[systemId.length -1],systemPath:systemId.join(',')});
+ const resp = await addData({ ...formVal, systemId:currentSelectedTreeNode.code });
set_reload(true);
if (type == 'EDIT') {
- const resp = await editData({ ...formVal,systemId:systemId[systemId.length -1],systemPath:systemId.join(',')});
+ const resp = await editData({ ...formVal, systemId:currentSelectedTreeNode.code});
@@ -134,12 +164,12 @@ export default function ParamsMana() {
title={`${type == 'EDIT' ? '编辑' : '新增'}参数`}
width={352}
- initialValues={type == 'EDIT' ? { ...record,systemId:record.systemPath?record.systemPath.split(','):[] } : {}}
+ initialValues={type == 'EDIT' ? { ...record } : {}}
trigger={
type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
onFinish={(val) => {
- return updateTable(type == 'ADD'?val:{...record,...val}, type); //编辑时将id返回去
+ return updateTable(type == 'ADD' ? val : { ...record, ...val }, type); //编辑时将id返回去
@@ -160,71 +190,6 @@ export default function ParamsMana() {
placeholder="请输入"
rules={[{ required: true, message: '参数值不能为空!' }]}
- {/* <ProFormDigit label="参数值" name="value" rules={[{ required: true, message: '参数值不能为空!' }]} /> */}
- <ProFormSelect
- name="hospId"
- label="院区:"
- placeholder="请选择院区"
- rules={[{ required: true, message: '院区不能为空!' }]}
- request={async () => {
- const resp = await getAllHosp({ pageSize: 200, current: 1 });
- const data: any = resp.list?.map((a) => ({
- label: a.hospName,
- value: a.id
- return [
- label:'所有院区',
- value:'0'
- },...data
- ];
- return []
- <ProFormCascader
- name='systemId'
- label="系统:"
- rules={[{ required: true, message: '系统不能为空!' }]}
- placeholder="请选择"
- const resp = await getSysLists();
- return resp
- fieldProps={{
- fieldNames: {
- label: 'name',
- value: 'code'
- name="status"
- label="启用:"
- buttonStyle: 'solid'
- rules={[{ required: true, message: '启用不能为空!' }]}
</ModalForm>
@@ -239,91 +204,211 @@ export default function ParamsMana() {
})
+ const getTreeReqFunc = async () => {
+ const resp = await getSysLists();
+ set_treeData(resp);
+ if (node.children.some((item: { code: React.Key; }) => item.code === key)) {
+ parentKey = node.code;
+ const { code, name } = node;
+ dataList.push({ code, name: name });
+ return getParentKey(item.code, treeData);
+ set_tableDataFilterParams({ ...tableDataFilterParams, systemId: currentSelectedTreeNode.code })
+ setExpandedKeys([nodeParent.code]);
+ set_defaultSelectedKeys([node.code])
+ } else if (treeData[0]) {
+ set_currentSelectedTreeNode(treeData[0]);
+ set_defaultSelectedKeys([treeData[0].code])
+ }, [])
- <div className='toolBar'>
- <div className='filter'>
- <div className='filterItem'>
- <span className='label'>适用院区:</span>
- noStyle
- allowClear
- style={{ width: 160, marginRight: 16 }}
- label: '所有院区', value: '0'
- }, ...data
- onChange(value, option) {
- set_tableDataFilterParams({ ...tableDataFilterParams, hospId: value })
- <div className='filterItem' style={{ marginRight: 16 }}>
- <span className='label'>系统名称:</span>
- width={160}
+ <div className='paramsMana'>
+ <div className='wrap'>
+ fieldNames={{ title: 'name', key: 'code' }}
+ rootStyle={{ height: '100%',overflowX: 'hidden',padding:16}}
+ selectedKeys={currentSelectedTreeNode ? [currentSelectedTreeNode.code] : []}
+ const copyFunc = async () => {
+ try {
+ await navigator.clipboard.writeText(nodeData.systemId);
+ message.success('复制成功!');
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
- onChange(value: any, option: any) {
- set_tableDataFilterParams({ ...tableDataFilterParams, systemId: value ? value[value.length - 1] : '' })
+ <KCInput placeholder={'请输入参数名称'} style={{ width: 160 }} search allowClear
+ parameterName: ''
+ onSearch={() => tableDataSearchHandle('parameterName')}
- <span className='label'>检索:</span>
- <KCInput placeholder={'请输入参数名称'} style={{ width: 160 }} search allowClear
- onChange={(e) => {
- set_tableDataSearchKeywords(e.target.value);
- if (e.target.value.length == 0) {
- set_tableDataFilterParams({
- ...tableDataFilterParams,
- parameterName: ''
- onSearch={() => tableDataSearchHandle('parameterName')}
+ <UpDataActBtn record type='ADD' />
- <UpDataActBtn record type='ADD' />
+ {currentSelectedTreeNode && <KCTable columns={columns} scroll={{ y: `calc(100vh - 250px)` }} reload={reload} rowKey='id' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />}
- <div style={{ marginTop: 16 }}>
* @Date: 2023-03-03 16:31:27
- * @LastEditTime: 2023-03-08 16:58:00
+ * @LastEditTime: 2023-09-14 18:15:35
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicTypeMana/service.ts
@@ -28,10 +28,12 @@ export type PubDicTypeData = {
-export const getData = (params:{
+export const getParamsManaTableData = (params:{
systemId?:number;
hospId?:number;
parameterName?:string;
+ current?:number,
+ pageSize?:number
}) => {
return request<{
@@ -49,9 +51,14 @@ export const getData = (params:{
//获取所有系统列表
export const getSysLists = () => {
- return request('/centerSys/menu/getSystemList', {
- method: 'GET',
+ const currentHosp = localStorage.getItem('currentSelectedSubHop');
+ if(currentHosp){
+ const { id } = JSON.parse(currentHosp);
+ return request('/centerSys/hospital/getSystemList', {
+ params:{hospId:id}
@@ -111,3 +118,4 @@ export const delData = (id:number) => {
@@ -0,0 +1,123 @@
+.paramsMana {
+ .search {
@@ -2,339 +2,466 @@
- * @LastEditTime: 2023-03-10 17:36:08
+ * @LastEditTime: 2024-03-01 16:15:37
import { KCInput } from '@/components/KCInput';
import { ModalForm, ProFormDigit, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
+import { Input, message, Modal, Popconfirm, TreeProps } from 'antd';
import { getData, PubDicTypeData } from '../pubDicTypeMana/service';
-import { addPubDicRelaTbaleData, delData, editPubDicRelaTbaleData, getPubDicRelaTbaleData } from './service';
+import { addPubDicRelaTbaleData, delData, editPubDicRelaTbaleData, getLeftData, getPubDicRelaTbaleData, initReq } from './service';
+import { useLocation } from 'umi';
+let systemId = '';
+const currentSelectedTab = localStorage.getItem('currentSelectedTab');
+if (currentSelectedTab) {
+ const { systemId: id } = JSON.parse(currentSelectedTab as string);
+ systemId = id;
const PubDicMana = () => {
+ const [pageType, set_pageType] = useState<undefined | number>(undefined); // 1 公用字典 2 院区公用字典
+ const defaultColumns = [
+ title: '项目名称',
+ title: '项目代码',
+ title: '项目值',
+ title: '默认',
+ dataIndex: 'data.0.dictDefault',
+ return record.dictDefault == 1 ? '是' : '否';
+ dataIndex: pageType == 1 ? 'dictSort' : 'sort',
+ title: '扩展1',
+ dataIndex: 'expandOne',
+ title: '扩展2',
+ dataIndex: 'expandTwo',
+ const options = [
+ const [columns, set_columns] = useState<any[]>([]);
+ const { dictType, systemId } = currentSelectedTreeNode;
+ if (dictType && pageType) {
+ const resp = await getPubDicRelaTbaleData({ ...params, dictType: params.dictType ? params.dictType : currentSelectedTreeNode.dictType, systemId }, pageType);
+ if (pageType) {
+ const resp = await delData(pageType == 1 ? record.dictDataId : record.id, pageType);
+ const updateTable = async (formVal: any, type: 'EDIT' | 'ADD') => {
+ const { systemId: parentId } = currentSelectedTreeNode;
+ let hospId = '0';
+ // if (currentSelectedHop) {
+ // const { id } = JSON.parse(currentSelectedHop);
+ // hospId = id
+ if (type == 'EDIT' && pageType) {
+ const resp = await editPubDicRelaTbaleData(
+ pageType == 1 ? { ...formVal, systemId: parentId, hospId, dictType: currentSelectedTreeNode?.dictType } : { ...formVal, systemId: parentId, hospId, type: currentSelectedTreeNode?.dictType },
+ pageType,
+ if (type == 'ADD' && pageType) {
+ const resp = await addPubDicRelaTbaleData(
- const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
- const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
- const [reload, set_reload] = useState(false);
- const [typeList, set_typeList] = useState<PubDicTypeData[]>([]);
- const [showTypeListArr, set_showTypeListArr] = useState<PubDicTypeData[]>([]);
- const [currentSelectedType, set_currentSelectedType] = useState<PubDicTypeData | undefined>(undefined);
- const [currentEdit,set_currentEdit] = useState<any>(undefined);
- title: '项目名称',
- dataIndex: 'name',
- title: '项目代码',
- dataIndex: 'code',
- title: '项目值',
- dataIndex: 'value',
- title: '默认',
- dataIndex: 'data.0.dictDefault',
- render: (_: any, record:any) => {
- return record.dictDefault == 1 ? '是' : '否'
+ const UpDataActBtn = ({ record, type }: { record: any; type: 'EDIT' | 'ADD' }) => {
+ title={`${type == 'EDIT' ? '编辑' : '新增'}公用字典(职称)`}
+ trigger={type == 'EDIT' ? <a key="edit">编辑</a> : <span className="add">新增</span>}
+ return updateTable(type == 'EDIT' ? (pageType == 1 ? { ...val, dictDataId: record.dictDataId } : { ...val, id: record.id }) : val, type);
+ <ProFormText name="name" label="项目名称:" placeholder="请输入" rules={[{ required: true, message: '项目名称不能为空!' }]} />
+ <ProFormText name="code" label="项目代码:" placeholder="请输入" rules={[{ required: true, message: '项目代码不能为空!' }]} />
+ <ProFormText name="value" label="项目值:" placeholder="请输入" />
+ <ProFormDigit label="顺序号:" name={pageType == 1 ? 'dictSort' : 'sort'} rules={[{ required: true, message: '顺序号不能为空!' }]} />
+ name={pageType == 1 ? 'dictDefault' : 'defaultFlag'}
+ label="默认:"
+ buttonStyle: 'solid',
- title: '序号',
- dataIndex: 'dictSort',
- title: '适用院区',
- title: '操作',
- key: 'option',
- width: 120,
- valueType: 'option',
- <UpDataActBtn key={'act'} record={record} type='EDIT' />,
- <Popconfirm
- title="是否确认删除?"
- key="del"
- onConfirm={() => delTableData(record)}
- <a>删除</a>
- </Popconfirm>
- const getTableData = async (params: any) => {
- const { dictType } = params;
- if (dictType) {
- const resp = await getPubDicRelaTbaleData(params);
- set_reload(false);
- data: resp.list,
- total: resp.totalCount,
- pageSize: resp.pageSize,
- totalPage: resp.totalPage,
+ rules={[{ required: true, message: '默认不能为空!' }]}
+ {true && (
+ <ProFormText name="expandOne" label="扩展一:" placeholder="请输入" />
+ <ProFormText name="expandTwo" label="扩展二:" placeholder="请输入" />
+ const getTreeReqFunc = async (type: number) => {
+ const resp = await getLeftData(type);
+ const transformResp = resp.map((a: any, index: number) => {
+ code: Math.random(),
+ children: a.dictTypeList.map((b: any, num: number) => ({ ...b, name: b.dictName, code: Math.random() })),
+ set_treeData(transformResp);
+ if (node.children.some((item: { code: React.Key }) => item.code === key)) {
- const getTypeList = async () => {
- const resp = await getData({ pageSize: 1000, current: 1 });
- set_typeList(resp.list);
- set_showTypeListArr(resp.list);
+ if (!data) return;
- const delTableData = async (record: any) => {
- const resp = await delData(record.dictDataId);
+ const newExpandedKeys = dataList.map((item) => {
+ const initFunction = () => {
+ title: '注意',
+ content: '初始化操作会覆盖已有的字典数据并根据默认数据生成字典数据,确定继续操作?',
+ onOk: async (...args) => {
+ const { systemId, dictType } = currentSelectedTreeNode;
+ const resp = await initReq(systemId, dictType);
+ message.success('初始化成功!');
- const updateTable = async (formVal: any, type: 'EDIT' | "ADD") => {
- if (type == 'EDIT') {
- const resp = await editPubDicRelaTbaleData({...formVal});
- set_reload(true);
- if (type == 'ADD') {
- const resp = await addPubDicRelaTbaleData({...formVal,dictType:currentSelectedType?.dictType});
+ const { topic = '' } = currentSelectedTreeNode;
+ const titles = topic.split('|');
+ if (topic && titles.length == 7) {
+ const newColumns = defaultColumns.map((a, index) => ({
+ title: titles[index],
+ set_columns([...newColumns, ...options]);
+ set_columns([...defaultColumns, ...options]);
- const UpDataActBtn = ({ record, type }: { record: any, type: 'EDIT' | 'ADD' }) => {
- <ModalForm
- title={`${type == 'EDIT' ? '编辑' : '新增'}公用字典(职称)`}
- width={352}
- initialValues={type == 'EDIT' ? { ...record } : {}}
- trigger={
- type == 'EDIT' ? <a key="edit" >编辑</a> : <span className='add'>新增</span>
- onFinish={(val) => {
- return updateTable(type == 'EDIT'?{...val,dictDataId:record.dictDataId}:val, type);
- label="项目名称:"
- rules={[{ required: true, message: '项目名称不能为空!' }]}
- name="code"
- label="项目代码:"
- rules={[{ required: true, message: '项目代码不能为空!' }]}
- name="value"
- label="项目值:"
- <ProFormDigit label="顺序号:" name="dictSort" rules={[{ required: true, message: '顺序号不能为空!' }]} />
- name="dictDefault"
- label="默认:"
- rules={[{ required: true, message: '默认不能为空!' }]}
- label="适用院区:"
- label:'所有院区',value:'0'
- </ModalForm>
- const editHandle = (record: any) => {
- const tableDataSearchHandle = (paramName: string) => {
- [`${paramName}`]: tableDataSearchKeywords
- if(currentSelectedType){
- set_tableDataFilterParams({...tableDataFilterParams,dictType:currentSelectedType.dictType})
- },[currentSelectedType])
- if (showTypeListArr.length > 0) {
- set_currentSelectedType(showTypeListArr[0]);
- set_tableDataFilterParams({ ...tableDataFilterParams, dictType: showTypeListArr[0].dictType });
- }, [showTypeListArr])
- getTypeList();
- <div className='PubDicMana'>
- <KCInput placeholder={'请输入类目名称'} search allowClear
- const result = typeList.filter(item=>item.dictName.indexOf(e.target.value) != -1);
- set_showTypeListArr(result);
+ if (pathname == '/platform/setting/pubDicMana/1') set_pageType(1);
+ if (pathname == '/platform/setting/pubDicMana/2') set_pageType(2);
+ }, [location]);
+ if (pageType) getTreeReqFunc(pageType);
+ }, [pageType]);
+ <div className="PubDicMana">
+ <div className="search">
+ <Input className="searchInput" placeholder="请输入" size="small" allowClear style={{ marginBottom: 16 }} onChange={onTreeSearchKeyChange} suffix={<SearchIcon type="iconsousuo" />} />
+ {treeData && treeData.length > 0 && (
+ rootStyle={{ height: '100%', paddingBottom: 50 }}
+ titleRender={(nodeData: any) => {
+ <span className="site-tree-search-value" style={{ color: 'red', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
+ {searchValue}
+ <span className="strTitle">{strTitle}</span>
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ height: 32,
+ whiteSpace: 'nowrap',
- showTypeListArr.map((item, index) => {
- <div className={currentSelectedType ? currentSelectedType.dictId == item.dictId ? 'type on' : 'type' : 'type'}
- key={index}
- onClick={() => set_currentSelectedType(item)}
- >{item.dictName}</div>
- style={{ width: 160,marginRight:16}}
- set_tableDataFilterParams({...tableDataFilterParams,hospId:value})
- <KCInput placeholder={'请输入项目名称'} style={{ width: 160 }} search allowClear
- typeName: ''
- onSearch={() => tableDataSearchHandle('typeName')}
- {currentSelectedType && <KCTable columns={columns as ProColumns[]} reload={reload} rowKey='dictDataId' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />}
+ {title}
+ defaultSelectedKeys={[treeData[0].children[0].code]}
+ return !expanded ? (
+ <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} />
+ <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
+ <span className="label">检索:</span>
+ placeholder={'请输入项目名称'}
+ set_tableDataFilterParams(
+ pageType == 1
+ typeName: '',
+ : { ...tableDataFilterParams, dictName: '' },
+ onSearch={() => tableDataSearchHandle(pageType == 1 ? 'typeName' : 'dictName')}
+ {pageType == 2 && (
+ <span className="initBtn" onClick={() => initFunction()}>
+ 初始化
+ {currentSelectedTreeNode && (
+ <KCTable
+ scroll={{ y: `calc(100vh - 250px)` }}
+ columns={columns as ProColumns[]}
+ reload={reload}
+ rowKey={pageType == 1 ? 'dictDataId' : 'id'}
+ newVer
+ params={tableDataFilterParams}
+ request={(params) => getTableData(params)}
export default PubDicMana;
* @Date: 2023-03-07 11:12:10
- * @LastEditTime: 2023-03-08 17:04:57
+ * @LastEditTime: 2023-09-08 11:23:11
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/pubDicMana/service.ts
@@ -24,14 +24,24 @@ export type PubDicRelaTbaleDataType = {
hospId?:string;
-export const getPubDicRelaTbaleData = (params:PubDicRelaTbaleDataType) => {
- return request('/centerSys/sysdictdata/getDictDataList', {
+export const getPubDicRelaTbaleData = (params:PubDicRelaTbaleDataType,pageType:number) => {
+ return request(pageType == 1?'/centerSys/sysdictdata/getDictDataList':'/centerSys/sysdictdata/getHospDict', {
method: 'GET',
params:{...params}
+//获取左侧列表数据
+export const getLeftData = (pageType:number) => {
+ return request(pageType == 1?'/centerSys/sysdictdata/getSystemDictTypeList':'/centerSys/sysdictdata/getHospSystemDictTypeList', {
//新增表格数据
export type AddPubDicRelaTbaleDataType = {
@@ -44,8 +54,8 @@ export type AddPubDicRelaTbaleDataType = {
hospId:number;
-export const addPubDicRelaTbaleData = (data:AddPubDicRelaTbaleDataType) => {
- return request('/centerSys/sysdictdata/addData', {
+export const addPubDicRelaTbaleData = (data:AddPubDicRelaTbaleDataType,pageType:number) => {
+ return request(pageType == 1?'/centerSys/sysdictdata/addData':'/centerSys/sysdictdata/addHospDict', {
method: 'POST',
data
@@ -64,8 +74,8 @@ export type EditPubDicRelaTbaleDataType = {
-export const editPubDicRelaTbaleData = (data:EditPubDicRelaTbaleDataType) => {
- return request('/centerSys/sysdictdata/editData', {
+export const editPubDicRelaTbaleData = (data:EditPubDicRelaTbaleDataType,pageType:number) => {
+ return request(pageType == 1?'/centerSys/sysdictdata/editData':'/centerSys/sysdictdata/editHospDict', {
@@ -73,9 +83,18 @@ export const editPubDicRelaTbaleData = (data:EditPubDicRelaTbaleDataType) => {
//删除表格操作
-export const delData = (dictDataId:string) => {
- return request('/centerSys/sysdictdata/deleteData', {
+export const delData = (dictDataId:string,pageType:number) => {
+ return request(pageType == 1?'/centerSys/sysdictdata/deleteData':'/centerSys/sysdictdata/deleteHospDict', {
- params:{dictDataId}
+ params:pageType == 1?{dictDataId}:{id:dictDataId}
+//初始化
+export const initReq = (systemId:string,dictType:string) => {
+ return request('/centerSys/sysdictdata/initHospDict', {
+ params:{systemId,dictType}
@@ -6,39 +6,63 @@
float: left;
width: 220px;
- height:calc(100vh - 80px);
- overflow: scroll;
.wrap {
- margin-top: 16px;
- .type {
- line-height: 32px;
- padding-left: 8px;
+ height: calc(100vh - 152px);
- margin-bottom: 4px;
- &.on {
- font-weight: 500;
- background: #F0F2F5;
@@ -69,6 +93,20 @@
+ .initBtn {
+ width: 72px;
.add {
@@ -2,137 +2,164 @@
- * @LastEditTime: 2023-03-24 12:10:56
+ * @LastEditTime: 2024-03-01 15:54:23
-import { getAllHosp } from '@/service/hospList';
-import { ModalForm, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form'
+import { ModalForm, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
-import { message, Modal, Popconfirm } from 'antd';
-import { addData, delData, editData, getData } from './service';
+import React, { useEffect, useState } from 'react';
-export default function PubDicTypeMana() {
- title: '类型名称',
- dataIndex: 'dictName',
- title: '类型代码',
- dataIndex: 'dictType',
- title: '说明',
- dataIndex: 'remark',
- // title: '院区',
- // dataIndex: 'hospName',
- onConfirm={()=>delTableData(record)}
+ title: '类型名称',
+ dataIndex: 'dictName',
+ title: '类型代码',
+ dataIndex: 'dictType',
+ title: '标题',
+ dataIndex: 'topic',
+ dataIndex: 'remark',
+ return <Switch size="small" checked={val == '0' ? true : false} onChange={(bool) => chnageDicOpenStatHandle(bool, record)} />;
+ const resp = await dicOpenStatHandle({ dictId: record.dictId, status: bool ? '0' : '1' });
+ message.success('开放成功!');
- const delTableData = async (record:any)=>{
- const resp = await delData(record.dictId);
- // message.success('操作成功!');
+ const resp = await getData({ ...params, systemId: params.systemId ? params.systemId : currentSelectedTreeNode.code });
- const resp = await addData({...formVal,hospId:0});
- const {dictId} = currentEdit;
- const resp = await editData({...formVal,dictId,hospId:0});
+ const resp = await delData(record.dictId);
+ dictName: formVal.dictName,
+ dictType: formVal.dictType,
+ remark: formVal.remark,
+ topic: formVal.topic ? formVal.topic : null,
+ systemId: currentSelectedTreeNode.code,
+ const { dictId } = currentEdit;
+ dictId,
- title={`${type == 'EDIT' ? '编辑' : '新增'}公用字典类型`}
- type == 'EDIT' ? <a key="edit" onClick={() => set_currentEdit(record)}>编辑</a> : <span className='add'>新增</span>
- return updateTable(val, type);
- {/* <ProFormSelect
+ title={`${type == 'EDIT' ? '编辑' : '新增'}公用字典类型`}
+ type == 'EDIT' ? (
+ <a key="edit" onClick={() => set_currentEdit(record)}>
+ 编辑
+ </a>
+ <span className="add">新增</span>
+ {/* <ProFormSelect
name="hospId"
label="院区:"
disabled={type == 'EDIT'}
@@ -155,69 +182,223 @@ export default function PubDicTypeMana() {
/> */}
- name="dictName"
- label="类型名称:"
- rules={[{ required: true, message: '类型名称不能为空!' }]}
- name="dictType"
- label="类型代码:"
- rules={[{ required: true, message: '类型代码不能为空!' }]}
- name="remark"
- label="说明:"
+ <ProFormText name="dictName" label="类型名称:" placeholder="请输入" rules={[{ required: true, message: '类型名称不能为空!' }]} />
+ <ProFormText name="dictType" label="类型代码:" placeholder="请输入" rules={[{ required: true, message: '类型代码不能为空!' }]} />
+ <ProFormTextArea name="topic" label="标题(|线分割):" placeholder="请输入" />
+ <ProFormTextArea name="remark" label="说明:" placeholder="请输入" />
- <KCInput placeholder={'请输入类型名称'} style={{ width: 160 }} search allowClear
+ <div className="PubDicTypeMana">
+ <a className="copy" onClick={() => copyFunc()}>
+ <img style={{ width: 14, height: 14 }} src={require('../../../../../public/images/copy.png')} alt="" />
+ <span className="strTitle">
+ {strTitle}
+ placeholder={'请输入类型名称'}
+ onSearch={() => tableDataSearchHandle('typeName')}
- <KCTable columns={columns as ProColumns[]} reload={reload} rowKey='dictId' newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />
+ {currentSelectedTreeNode && <KCTable columns={columns as ProColumns[]} reload={reload} rowKey="dictId" newVer params={tableDataFilterParams} request={(params) => getTableData(params)} />}
@@ -2,86 +2,88 @@
- * @LastEditTime: 2023-03-07 10:28:57
+ * @LastEditTime: 2024-03-01 15:47:56
import { request } from 'umi';
//获取table列表数据
export type PubDicTypeData = {
- dictId:string;
- dictName:string;
- dictType:string;
- hospId:string;
- hospName:string;
- remark:string;
- status:string
+ dictId: string;
+ dictName: string;
+ dictType: string;
+ hospName: string;
+ remark: string;
+ status: string;
-export const getData = (params?:any) => {
- return request<{
- current:number;
- list:PubDicTypeData[];
- pageSize:number;
- totalCount:number;
- totalPage:number;
- }>('/centerSys/sysdictdata/getDictType', {
+ return request('/centerSys/sysdictdata/getSystemDict', {
- params:{...params}
export type AddTableDataType = {
- hospId:number;
- remark:string
-export const addData = (data:AddTableDataType) => {
- return request('/centerSys/sysdictdata/addDictType', {
+ topic: string;
+ return request('/centerSys/sysdictdata/addSystemDict', {
- data
+ if (currentHosp) {
+ params: { hospId: id },
//编辑表格数据
export type EditTableDataType = {
- dictId:number;
+ dictId: number;
-export const editData = (data:EditTableDataType) => {
- return request('/centerSys/sysdictdata/editDictType', {
+export const editData = (data: EditTableDataType) => {
+ return request('/centerSys/sysdictdata/editSystemDict', {
-export const delData = (dictId:string) => {
- return request('/centerSys/sysdictdata/deleteDictType', {
+export const delData = (dictId: string) => {
+ return request('/centerSys/sysdictdata/deleteSystemDict', {
- params:{dictId}
+ params: { dictId },
+export const dicOpenStatHandle = (data: { dictId: string; status: string }) => {
+ return request('/centerSys/sysdictdata/editSystemDictStatus', {
+ params: { ...data },
@@ -1,42 +1,116 @@
.PubDicTypeMana {
- padding: 16px;
- .toolBar {
- .filter {
+ display:none;
+ width:16px;
+ height:16px;
+ border-radius:4px;
+ border:1px solid #DAE2F2;
+ margin-left:4px;
+ position:relative;
+ top:2px;
- .filterItem {
- .btnGroup {
- .add {
- line-height: 24px;
- padding: 0 14px;
- background: #3377FF;
* @Date: 2022-03-03 18:04:40
- * @LastEditTime: 2023-02-27 14:16:42
+ * @LastEditTime: 2023-05-30 15:46:46
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/reports/index.tsx
@@ -15,8 +15,8 @@ export default () => {
const [specialPageUrl, setspecialPageUrl] = useState<string | undefined>(undefined);
const [loading, setloading] = useState(false);
- console.log('reports');
const onLoadhandle = () => {
setloading(false);
@@ -24,6 +24,11 @@ export default () => {
setloading(true);
+ }, [initialState]);
+ useEffect(()=>{
+ console.log({pathname});
if (initialState && initialState.spacicalPageParamsType && initialState.userData) {
spacicalPageParamsType,
@@ -42,10 +47,7 @@ export default () => {
setspecialPageUrl(url);
- console.log({specialPageUrl});
- }, [initialState]);
+ },[pathname])
- * @LastEditTime: 2023-03-17 16:33:16
+ * @LastEditTime: 2024-01-10 16:50:30
@@ -13,7 +13,7 @@ import KCProSelect from '@/components/KCProSelect';
import { roleManageModelState, Dispatch } from 'umi';
import { ProFormText, ProFormTextArea } from '@ant-design/pro-form';
-import { getHospList } from '@/service/hospList';
+import { getHospList, getShareHospList } from '@/service/hospList';
import { AddUsersDataType, getYoushuUsers } from '@/service/user';
import { TableActType } from '..';
@@ -104,7 +104,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
{tableAct == TableActType.EDITRELAUSER && (
<Form.Item name="bindUserIds">
- <UserEditer total={currentEdit?currentEdit.allUsers:[]} noAction={true} />
+ <UserEditer total={currentEdit ? currentEdit.allUsers : []} noAction={true} />
@@ -116,7 +116,7 @@ const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, cu
disabled
+ const hospList = await getShareHospList();
return hospList.map((t) => ({
- * @LastEditTime: 2022-01-19 17:28:09
+ * @LastEditTime: 2023-09-18 17:59:16
@@ -141,11 +141,15 @@ const roleManageModel: roleManageModelType = {
return id;
*addEffect({ payload }, { put }) {
- const { id } = yield getMainHosp();
- yield put({
- type: 'add',
- payload: { hospId: id },
+ // const { id } = yield getMainHosp();
+ const {id} = JSON.parse(currentHosp);
+ yield put({
+ type: 'add',
+ payload: { hospId: id },
reducers: {
@@ -1,3 +1,214 @@
+.setApiPermDrawer_roleMana {
+ .topbar {
+ line-height:16px;
+ .cancel {
+ .save {
+ color: #fff;
+ .leftTree {
+ height:calc(100vh - 72px);
+ float: left;
+ background: #FFF;
+ .kcmp-ant-tree.kcmp-ant-tree-directory .kcmp-ant-tree-treenode-selected:hover::before,
+ .kcmp-ant-tree.kcmp-ant-tree-directory .kcmp-ant-tree-treenode-selected::before {
+ .rightContent {
+ // padding: 16px;
+ margin-left: 236px;
+ .checkBtn {
+ background: #3376FE;
+ color: #FFF;
+ .midLine {
+ background: #F0FCFC;
+ margin-top: 12px;
+ margin-bottom: 15px;
+ color: #00B3B3;
+ padding-right: 4px;
+ .kcmp-ant-tabs-nav {
+ .tableToolbar {
+ .tixiMenuSet {
+ .despcrip {
+ height: 14px;
+ line-height: 14px;
+ color: #7A8599;
.RoleManage {
height: auto;
@@ -40,4 +251,5 @@
@@ -0,0 +1,52 @@
+ * @Author: your name
+ * @Date: 2022-03-03 18:04:40
+ * @LastEditTime: 2023-08-08 14:45:58
+ * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/reports/index.tsx
+import { Skeleton } from 'antd';
+import { useModel } from 'umi';
+export default () => {
+ const [loading, setloading] = useState(false);
+ setloading(false);
+ setloading(true);
+ if (initialState && initialState.spacicalPageParamsType && initialState.userData) {
+ const {
+ spacicalPageParamsType,
+ userData: { youshuToken },
+ } = initialState;
+ console.log({ spacicalPageParamsType });
+ const spacialPage = spacicalPageParamsType.filter((t) => t.path == pathname);
+ if (spacialPage.length > 0) {
+ //当前页面属于有数数据展示页面
+ console.log(`${spacialPage[0].url}`);
+ const url = `${spacialPage[0].url}`;
+ setspecialPageUrl(url);
+ <Skeleton loading={loading} paragraph={{ rows: 50 }} active />
+ <iframe onLoad={() => onLoadhandle()} style={{ width: '100%', height: '90vh', border: 'none' }} src={specialPageUrl}></iframe>
@@ -1,18 +1,12 @@
* @Date: 2022-12-16 09:42:52
- * @LastEditTime: 2023-03-23 17:33:53
+ * @LastEditTime: 2023-11-10 10:25:38
* @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlySet/index.tsx
import { useEffect, useImperativeHandle, useRef, useState } from 'react';
@@ -24,7 +18,7 @@ import closeIcon from '../../../../../public/images/treenode_collapse.png';
import type { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
import { createFromIconfontCN } from '@ant-design/icons';
-import { addData, delData, editData, getMenuRelaActDic, getTableDataRequest, getTreeData, getTreeDataRespType, updateFuncDic } from './service';
+import { addData, delData, editData, getMenuContentType, getMenuRelaActDic, getTableDataRequest, getTreeData, getTreeDataRespType, updateFuncDic } from './service';
import { TransferDirection, TransferItem } from 'antd/es/transfer';
import difference from 'lodash/difference';
@@ -37,759 +31,712 @@ import DirectoryTree from 'antd/es/tree/DirectoryTree';
import { ActionType, ProColumns } from '@ant-design/pro-table';
import { getDeepestTreeData } from '@/utils';
-import ProForm, { ModalForm, ProFormDependency, ProFormDigit, ProFormItem, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
+import ProForm, { ModalForm, ProFormDependency, ProFormDigit, ProFormInstance, ProFormItem, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
import { UserRelaSeletDataListType } from '@/service/user';
const IconFont = createFromIconfontCN({
- scriptUrl: '//at.alicdn.com/t/c/font_1927152_4nm5kxbv4m3.js',
+ scriptUrl: '//at.alicdn.com/t/c/font_1927152_4nm5kxbv4m3.js',
const SearchIcon = createFromIconfontCN({
- scriptUrl: '//at.alicdn.com/t/c/font_1927152_g1njmm1kh7b.js',
export type TableListItem = {
- key: number;
+ key: number;
const MonthlyInfoCheck: React.FC = () => {
- const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
- const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();
- const [searchValue, setSearchValue] = useState('');
- const [autoExpandParent, setAutoExpandParent] = useState(true);
- const [currentOperateRow, set_currentOperateRow] = useState<any | undefined>(undefined); //当前操作的表格行数据
- const tableRef = useRef<ActionType>();
- const transferTableColumn = [
- title: '功能名称',
- key: 'name',
- title: '功能代码',
- key: 'code',
- title: '名称',
- title: '类型',
- dataIndex: 'contentType',
- key: 'contentType',
- //console.log({ record });
- switch (record.type) {
- case 0:
- return '目录'
- case 1:
- return '菜单'
- case 2:
- return 'api'
- case 3:
- return '系统'
- case 4:
- return '有数bi'
- case 5:
- return '体系'
- case 6:
- return '中心层'
- case 7:
- return '平台层'
- default:
- break;
- title: 'Path',
- dataIndex: 'path',
- key: 'path',
- title: '内容',
- valueEnum: {
- 0: '一般',
- 1: '报告',
- 2: '大屏',
- 3: '填报',
- 4: '空白'
- title: '功能',
- dataIndex: 'deptName',
- key: 'deptName',
- if (record.functionList) {
- return record.functionList.reduce((prev: any, cur: any) => {
- return `${prev ? prev + ' | ' : prev}${cur.name}`
- }, '')
- return '-'
- fixed: 'right',
- return record.type != 1 && record.type != 2 && record.type != 4 ? [
- <UpDataActBtn key={'add'} record={record} type='ADD' />,
- onConfirm={() => delMenuHandle(record)}
- ] : [
- <a key={'fuc'} onClick={() => addFuncHandle(record)}>功能</a>,
- const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
- //console.log('selected', selectedKeys, info);
- const { node } = info;
- set_currentSelectedTreeNode(node);
- const getTableData = async (params: any, sort: any, filter: any) => {
- if (currentSelectedTreeNode) {
- const resp = await getTableDataRequest(params);
- data: resp,
- data: [],
- success: true
+ const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
+ const [currentOperateRow, set_currentOperateRow] = useState<any | undefined>(undefined); //当前操作的表格行数据
+ const [contentType, set_contentType] = useState<any[]>([]); //菜单内容类型列表
+ const tableRef = useRef<ActionType>();
+ const transferTableColumn = [
+ title: '功能名称',
+ key: 'name',
+ title: '功能代码',
+ key: 'code',
+ title: '名称',
+ ellipsis: true,
+ title: '类型',
+ dataIndex: 'contentType',
+ key: 'contentType',
+ width: 100,
+ //console.log({ record });
+ switch (record.type) {
+ case 0:
+ return '目录';
+ case 1:
+ return '菜单';
+ case 2:
+ return 'api';
+ case 3:
+ return '系统';
+ case 4:
+ return '有数bi';
+ case 5:
+ return '体系';
+ case 6:
+ return '中心层';
+ case 7:
+ return '平台层';
+ default:
+ break;
- const addFuncHandle = (record: any) => {
- set_currentOperateRow(record);
- const ref = React.createRef<{ save: any; }>();
- Modal.confirm({
- title: '菜单功能设置(核算单元管理)',
- width: 672,
- content: <TableTransfer
- ref={ref}
- record={record}
- leftColumns={transferTableColumn}
- rightColumns={transferTableColumn} dataSource={[]}
- ></TableTransfer>,
- onOk: () => {
- return ref.current && ref.current.save();
- const delMenuHandle = async (record: any) => {
- const resp = await delData(record.menuId);
- resp && set_reload(true);
- interface DataType {
- key: string;
- title: string;
- description: string;
- disabled: boolean;
- tag: string;
- interface TableTransferProps extends TransferProps<TransferItem> {
- dataSource: DataType[];
- leftColumns: ColumnsType<DataType>;
- rightColumns: ColumnsType<DataType>;
- record: any
- const TableTransfer = React.forwardRef(({ leftColumns, rightColumns, record, ...restProps }: TableTransferProps, ref) => {
- const [_data, _set_data] = useState<any>();
- const [targetKeys, setTargetKeys] = useState<string[]>([]);
- const [datasource, set_datasource] = useState<any[]>([]);
- const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
- //获取页面权限字典
- const getFuncList = async () => {
- const resp = await getMenuRelaActDic();
- set_datasource(resp);
- if (record && record.functionList) {
- const defaultSelctedkeys = record.functionList.map((item: any) => item.code);
- setTargetKeys(defaultSelctedkeys);
+ title: 'Path',
+ width: 300,
+ dataIndex: 'path',
+ key: 'path',
+ title: '内容',
+ valueEnum: {
+ 0: '一般',
+ 1: '报告',
+ 2: '大屏',
+ 3: '填报',
+ 4: '空白',
+ 5: '静态',
+ 6: '外部系统嵌入',
+ title: '功能',
+ dataIndex: 'deptName',
+ key: 'deptName',
+ if (record.functionList) {
+ return record.functionList.reduce((prev: any, cur: any) => {
+ return `${prev ? prev + ' | ' : prev}${cur.name}`;
+ }, '');
- const onChange = (nextTargetKeys: string[]) => {
- setTargetKeys(nextTargetKeys);
- const onSelectChange = (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => {
- //console.log('sourceSelectedKeys:', sourceSelectedKeys,'targetSelectedKeys:',targetSelectedKeys);
- setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
+ return '-';
+ fixed: 'right',
+ return record.type != 1 && record.type != 2 && record.type != 4
+ ? [
+ <UpDataActBtn key={'add'} record={record} type="ADD" />,
+ <Popconfirm title="是否确认删除?" key="del" onConfirm={() => delMenuHandle(record)}>
+ : [
+ <a key={'fuc'} onClick={() => addFuncHandle(record)}>
+ 功能
+ </a>,
+ const getContentType = async () => {
+ const currentSelectedTab = localStorage.getItem('currentSelectedTab');
+ const { systemId } = JSON.parse(currentSelectedTab as string);
+ const resp = await getMenuContentType(systemId);
+ set_contentType(resp.list);
+ const getTableData = async (params: any, sort: any, filter: any) => {
+ const resp = await getTableDataRequest(params);
+ data: resp,
+ data: [],
- useImperativeHandle(ref, () => ({
- save: async () => {
- const data = datasource.filter(item => targetKeys.includes(item.code));
- const resp = await updateFuncDic({
- menuId: record.menuId,
- function: data
- getFuncList();
- <Transfer className='TableTransfer' showSearch
- titles={['待选项目', '已选项目']}
- locale={{
- itemUnit: '项',
- itemsUnit: '项',
- searchPlaceholder: '请输入'
- onChange={onChange}
- onSelectChange={onSelectChange}
- dataSource={datasource}
- rowKey={record => record.code}
- targetKeys={targetKeys}
- selectedKeys={selectedKeys}
- filterOption={(inputValue, item) => {
- return item.name!.indexOf(inputValue) !== -1
- {({
- direction,
- filteredItems,
- onItemSelectAll,
- onItemSelect,
- selectedKeys: listSelectedKeys,
- disabled: listDisabled,
- }) => {
- // console.log({ filteredItems, listSelectedKeys,direction });
- const columns = direction === 'left' ? leftColumns : rightColumns;
- const rowSelection: TableRowSelection<TransferItem> = {
- getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
- onSelectAll(selected, selectedRows) {
- const treeSelectedKeys = selectedRows.map(({ code }) => code);
- const diffKeys = selected
- ? difference(treeSelectedKeys, listSelectedKeys)
- : difference(listSelectedKeys, treeSelectedKeys);
- onItemSelectAll(diffKeys as string[], selected);
- onSelect({ code }, selected) {
- onItemSelect(code as string, selected);
- selectedRowKeys: listSelectedKeys,
- <Table
- rowSelection={rowSelection}
- columns={columns as TransferItem[]}
- dataSource={filteredItems}
- size="small"
- rowKey={'code'}
- style={{ pointerEvents: listDisabled ? 'none' : undefined }}
- onRow={({ code, disabled: itemDisabled }) => ({
- onClick: () => {
- if (itemDisabled || listDisabled) return;
- onItemSelect(code as string, !listSelectedKeys.includes(code as string));
- })}
- </Transfer>
- const dataList: any[] = [];
- const getParentKey = (key: React.Key, tree: any[]): React.Key => {
- let parentKey: React.Key;
- for (let i = 0; i < tree.length; i++) {
- const node = tree[i];
- if (node.children) {
- if (node.children.some((item: { code: React.Key; }) => item.code === key)) {
- parentKey = node.code;
- } else if (getParentKey(key, node.children)) {
- parentKey = getParentKey(key, node.children);
+ const addFuncHandle = (record: any) => {
+ set_currentOperateRow(record);
+ const ref = React.createRef<{ save: any }>();
+ title: '菜单功能设置(核算单元管理)',
+ icon: '',
+ width: 672,
+ content: <TableTransfer ref={ref} record={record} leftColumns={transferTableColumn} rightColumns={transferTableColumn} dataSource={[]}></TableTransfer>,
+ return ref.current && ref.current.save();
+ const delMenuHandle = async (record: any) => {
+ const resp = await delData(record.menuId);
+ resp && set_reload(true);
+ interface DataType {
+ key: string;
+ title: string;
+ disabled: boolean;
+ tag: string;
+ interface TableTransferProps extends TransferProps<TransferItem> {
+ dataSource: DataType[];
+ leftColumns: ColumnsType<DataType>;
+ rightColumns: ColumnsType<DataType>;
+ record: any;
+ const TableTransfer = React.forwardRef(({ leftColumns, rightColumns, record, ...restProps }: TableTransferProps, ref) => {
+ const [_data, _set_data] = useState<any>();
+ const [targetKeys, setTargetKeys] = useState<string[]>([]);
+ const [datasource, set_datasource] = useState<any[]>([]);
+ const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
+ //获取页面权限字典
+ const getFuncList = async () => {
+ const resp = await getMenuRelaActDic();
+ set_datasource(resp);
+ if (record && record.functionList) {
+ const defaultSelctedkeys = record.functionList.map((item: any) => item.code);
+ setTargetKeys(defaultSelctedkeys);
- return parentKey!;
- const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- const { value } = e.target;
- const newExpandedKeys = dataList
- .map((item) => {
- if (item.name.indexOf(value) > -1) {
- return getParentKey(item.code, treeData);
- return null;
- const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);
- setExpandedKeys(newExpandedKeys as React.Key[]);
- setSearchValue(value);
- setAutoExpandParent(true);
- const onExpand = (newExpandedKeys: React.Key[]) => {
- setExpandedKeys(newExpandedKeys);
- setAutoExpandParent(false);
+ const onChange = (nextTargetKeys: string[]) => {
+ setTargetKeys(nextTargetKeys);
- const generateList = (data: getTreeDataRespType[]) => {
- for (let i = 0; i < data.length; i++) {
- const node = data[i];
- const { code, name } = node;
- dataList.push({ code, name: name });
- generateList(node.children);
+ const onSelectChange = (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => {
+ //console.log('sourceSelectedKeys:', sourceSelectedKeys,'targetSelectedKeys:',targetSelectedKeys);
+ setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
- generateList(treeData as any);
- const getTreeReqFunc = async (name?: string) => {
- const resp = await getTreeData();
- set_treeData(resp);
- const updateTable = async (type: 'EDIT' | "ADD", formVal: any, record: any) => {
+ useImperativeHandle(ref, () => ({
+ save: async () => {
+ const data = datasource.filter((item) => targetKeys.includes(item.code));
- let data = undefined;
- if (record) {
- //添加操作
- data = { ...formVal, parentId: record.menuId, systemId: record.systemId }
- //新增
- data = { ...formVal, parentId: currentSelectedTreeNode.code, systemId: currentSelectedTreeNode.code }
- const resp = await addData({ ...data });
+ const resp = await updateFuncDic({
+ menuId: record.menuId,
+ function: data,
- const resp = await editData({ ...record, ...formVal });
- set_currentOperateRow(undefined);
+ getFuncList();
- return true
+ className="TableTransfer"
+ titles={['待选项目', '已选项目']}
+ locale={{
+ itemUnit: '项',
+ itemsUnit: '项',
+ searchPlaceholder: '请输入',
+ onChange={onChange}
+ onSelectChange={onSelectChange}
+ dataSource={datasource}
+ rowKey={(record) => record.code}
+ targetKeys={targetKeys}
+ selectedKeys={selectedKeys}
+ filterOption={(inputValue, item) => {
+ return item.name!.indexOf(inputValue) !== -1;
+ {({ direction, filteredItems, onItemSelectAll, onItemSelect, selectedKeys: listSelectedKeys, disabled: listDisabled }) => {
+ // console.log({ filteredItems, listSelectedKeys,direction });
+ const columns = direction === 'left' ? leftColumns : rightColumns;
+ const rowSelection: TableRowSelection<TransferItem> = {
+ getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
+ onSelectAll(selected, selectedRows) {
+ const treeSelectedKeys = selectedRows.map(({ code }) => code);
+ const diffKeys = selected ? difference(treeSelectedKeys, listSelectedKeys) : difference(listSelectedKeys, treeSelectedKeys);
+ onItemSelectAll(diffKeys as string[], selected);
+ onSelect({ code }, selected) {
+ onItemSelect(code as string, selected);
+ selectedRowKeys: listSelectedKeys,
+ <Table
+ rowSelection={rowSelection}
+ columns={columns as TransferItem[]}
+ dataSource={filteredItems}
+ size="small"
+ rowKey={'code'}
+ style={{ pointerEvents: listDisabled ? 'none' : undefined }}
+ onRow={({ code, disabled: itemDisabled }) => ({
+ onClick: () => {
+ if (itemDisabled || listDisabled) return;
+ onItemSelect(code as string, !listSelectedKeys.includes(code as string));
+ </Transfer>
+ const generateList = (data: getTreeDataRespType[]) => {
+ const updateTable = async (type: 'EDIT' | 'ADD', formVal: any, record: any) => {
+ let data = undefined;
+ if (record) {
+ //添加操作
+ data = { ...formVal, parentId: record.menuId, systemId: record.systemId };
+ //新增
+ data = { ...formVal, parentId: currentSelectedTreeNode.code, systemId: currentSelectedTreeNode.code };
+ const resp = await addData({ ...data });
+ const resp = await editData({ ...record, ...formVal });
+ set_currentOperateRow(undefined);
- className='systemNavManaForm'
- title={`${type == 'EDIT' ? '编辑' : '新增'}菜单`}
- width={688}
- initialValues={type == 'EDIT' ? { ...record } : { isHomepage: 0 }}
- type == 'EDIT' ? <a key="edit" >编辑</a> : record ? <a className='add'>添加</a> : <span>新增</span>
- grid={true}
- return updateTable(type, val, record)
- label="名称:"
- colProps={{ span: 12 }}
- rules={[{ required: true, message: '名称不能为空!' }]}
- label="类型:"
- label: '目录',
- value: 0
- label: '菜单',
- value: 2
- rules={[{ required: true, message: '类型不能为空!' }]}
- label="Path:"
- rules={[{ required: true, message: 'Path不能为空!' }]}
- name="icon"
- label="icon:"
- //rules={[{ required: true, message: '类型代码不能为空!' }]}
- label="顺序号:"
- width={'xs'}
+ className="systemNavManaForm"
+ title={`${type == 'EDIT' ? '编辑' : '新增'}菜单`}
+ width={688}
+ initialValues={type == 'EDIT' ? { ...record } : { isHomepage: 0 }}
+ trigger={type == 'EDIT' ? <a key="edit">编辑</a> : record ? <a className="add">添加</a> : <span>新增</span>}
+ grid={true}
+ return updateTable(type, val, record);
+ <ProFormText name="name" label="名称:" placeholder="请输入" colProps={{ span: 12 }} rules={[{ required: true, message: '名称不能为空!' }]} />
+ label="类型:"
+ colProps={{ span: 12 }}
+ label: '目录',
+ label: '菜单',
+ rules={[{ required: true, message: '类型不能为空!' }]}
+ <ProFormText name="path" label="Path:" placeholder="请输入" colProps={{ span: 12 }} rules={[{ required: true, message: 'Path不能为空!' }]} />
+ name="icon"
+ label="icon:"
+ //rules={[{ required: true, message: '类型代码不能为空!' }]}
+ name="orderNum"
+ label="顺序号:"
+ width={'xs'}
+ {({ type }) =>
+ label="是否首页:"
+ rules={[{ required: true, message: '是否为首页不能为空!' }]}
//rules={[{ required: true, message: '类型代码不能为空!' }]}
- ({ type }) => type == 2 && (
- label="是否首页:"
- rules={[{ required: true, message: '是否为首页不能为空!' }]}
- <ProForm.Group colProps={{ span: 12 }} align='start'>
- label="内容类型:"
- width={100}
- colProps={{ span: 8 }}
- { label: '一般', value: 0 },
- { label: '报告', value: 1 },
- { label: '大屏', value: 2 },
- { label: '填报', value: 3 },
- { label: '空白', value: 4 },
- return contentType == 1 && (
- <div style={{ position: 'relative', top: 24 }}>
- width={210}
- className='reportId'
- placeholder="请输入报告Id"
- colProps={{ span: 16 }}
- </ProForm.Group>
+ <ProForm.Group colProps={{ span: 12 }} align="start">
+ label="内容类型:"
+ width={100}
+ colProps={{ span: 8 }}
+ if (contentType) {
+ return contentType.map((a: any) => ({ label: a.name, value: Number(a.code) }));
- label="URL:"
+ if (value == 1) {
+ //报告页面
+ const need = contentType.filter((item: any) => item.code == `${value}`);
+ if (need.length > 0) formRef.current?.setFieldValue('url', need[0].value);
+ // options={[
+ // { label: '一般', value: 0 },
+ // { label: '报告', value: 1 },
+ // { label: '大屏', value: 2 },
+ // { label: '填报', value: 3 },
+ // { label: '空白', value: 4 },
+ // { label: '静态', value: 5 },
+ // ]}
+ contentType == 1 && (
+ <div style={{ position: 'relative', top: 24 }}>
+ noStyle
+ width={210}
+ className="reportId"
+ placeholder="请输入报告Id"
+ colProps={{ span: 16 }}
</ProFormDependency>
+ </ProForm.Group>
+ label="URL:"
+ <ProFormTextArea name="description" label="描述:" placeholder="请输入" colProps={{ span: 24 }} />
- label="描述:"
- colProps={{ span: 24 }}
- set_tableDataFilterParams({ ...tableDataFilterParams, systemId: currentSelectedTreeNode.code })
- }, [currentSelectedTreeNode]);
- //初始化左侧树结构数据后
- if (treeData?.length > 0) {
- if (treeData[0].children && treeData[0].children.length > 0) {
- const [node, nodeParent] = getDeepestTreeData(treeData[0], 'children');
- setExpandedKeys([nodeParent.code]);
- }, [treeData]);
- getTreeReqFunc();
- }, []);
- <div className='SystemNavMana'>
- <div className='leftTree'>
- <div className='search'>
- <Input
- className='searchInput'
- size='small'
- style={{ marginBottom: 16 }}
- onChange={onTreeSearchKeyChange}
- suffix={
- <SearchIcon type='iconsousuo' />
+ getContentType();
+ <div className="SystemNavMana">
+ <div className="leftTree">
+ rootStyle={{ overflowY: 'scroll', overflowX: 'hidden' }}
- treeData && treeData.length > 0 && (
- <DirectoryTree
- fieldNames={{ title: 'name', key: 'code' }}
- rootStyle={{ height: '100%', paddingBottom: 50, overflowY: 'scroll', overflowX: 'hidden' }}
- onExpand={onExpand}
- autoExpandParent={autoExpandParent}
- selectedKeys={currentSelectedTreeNode ? [currentSelectedTreeNode.code] : []}
- blockNode={true}
- icon={() => null}
- titleRender={
- (nodeData: any) => {
- const strTitle = nodeData.name as string;
- const index = strTitle.indexOf(searchValue);
- const beforeStr = strTitle.substring(0, index);
- const afterStr = strTitle.slice(index + searchValue.length);
- const title =
- index > -1 ? (
- <span>
- {beforeStr}
- <span className="site-tree-search-value" style={{ color: 'red', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{searchValue}</span>
- {afterStr}
- </span>
- ) : (
- <span className='strTitle'>{strTitle}</span>
- return <div style={{
- display: 'flex', flexDirection: 'row',
- width: '100%',
- justifyContent: 'flex-start', alignItems: 'center', height: 32,
- borderRadius: '4px',
- overflow: 'hidden',
- color: '#17181A',
- textOverflow: 'ellipsis',
- whiteSpace: 'nowrap'
- }}>{title}</div>
- defaultSelectedKeys={[treeData[0].children[0].code]}
- treeData={treeData as unknown as DataNode[]}
- // treeData={treeDataNew}
- switcherIcon={(props: any) => {
- const { expanded } = props;
- //return <button className='site-table-row-expand-icon site-table-row-expand-icon-expanded'></button>
- return !expanded ? <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} /> : <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
+ {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
+ <div className="rightContent">
+ <div className="tableToolbar">
+ placeholder={'请输入菜单名称'}
- {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
- <div className='rightContent'>
- <div className='tableToolbar'>
- <KCInput placeholder={'请输入菜单名称'} style={{ width: 160 }} search allowClear
- name: ''
- onSearch={() => tableDataSearchHandle('name')}
- <div className={'btnGroup'}>
- <UpDataActBtn key={'act'} record={undefined} type='ADD' />
- {currentSelectedTreeNode && <KCTable pagination={false} reload={reload} newVer params={tableDataFilterParams} rowKey='menuId' columns={columns as ProColumns[]} request={(params: any, sort: any, filter: any) => getTableData(params, sort, filter)} />}
+ <div className={'btnGroup'}>
+ <UpDataActBtn key={'act'} record={undefined} type="ADD" />
+ pagination={false}
+ rowKey="menuId"
+ request={(params: any, sort: any, filter: any) => getTableData(params, sort, filter)}
-export default MonthlyInfoCheck;
+export default MonthlyInfoCheck;
@@ -2,171 +2,141 @@
* @Date: 2022-12-21 11:13:51
- * @LastEditTime: 2023-03-15 16:40:17
+ * @LastEditTime: 2023-11-10 10:26:29
* @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlyInfoCheck/service.ts
//获取树结构数据
export type getTreeDataRespType = {
- code: number;
- children: getTreeDataRespType[]
-export const getTreeData = (name?:string) => {
- return request<getTreeDataRespType[]>('/centerSys/navigation/getSystemList', {
- params: { name }
+ code: number;
+ children: getTreeDataRespType[];
+export const getTreeData = (name?: string) => {
+ return request<getTreeDataRespType[]>('/centerSys/navigation/getSystemList', {
+ params: { name },
+//获取菜单内容类型列表
+export const getMenuContentType = (systemId: string) => {
+ return request('/centerSys/sysdictdata/getDictDataList?current=1&pageSize=1000&dictType=MENU_CONTENT_TYPE', {
+ params: { systemId },
//获取表格数据
export type SystemRelaMenuDataType = {
- parentId:string;
- url:string;
- softUrl:string;
- perms:string;
- icon:string;
- orderNum:number;
- reportId:string;
- contentType:number;
- isHomepage:number;
- children:SystemRelaMenuDataType[]
-export const getTableDataRequest = (params:{systemId:string;name?:string}) => {
- return request<SystemRelaMenuDataType[]>('/centerSys/navigation/getMenuList', {
- params: { ...params }
+ parentId: string;
+ url: string;
+ softUrl: string;
+ perms: string;
+ icon: string;
+ orderNum: number;
+ reportId: string;
+ isHomepage: number;
+ children: SystemRelaMenuDataType[];
+export const getTableDataRequest = (params: { systemId: string; name?: string }) => {
+ return request<SystemRelaMenuDataType[]>('/centerSys/navigation/getMenuList', {
//新增菜单
export type AddMenuDataType = {
- parentId:number;
- type:string;
- systemId:number;
-export const addData = (data:AddMenuDataType) => {
- return request('/centerSys/navigation/addMenu', {
- method: 'POST',
+ parentId: number;
+ type: string;
+ contentType: string;
+ systemId: number;
+export const addData = (data: AddMenuDataType) => {
+ return request('/centerSys/navigation/addMenu', {
//编辑菜单
export type EditMenuDataType = {
- menuId:number;
-export const editData = (data:EditMenuDataType) => {
- return request('/centerSys/navigation/editMenu', {
+ menuId: number;
+export const editData = (data: EditMenuDataType) => {
+ return request('/centerSys/navigation/editMenu', {
//删除菜单
-export const delData = (menuId:number) => {
- return request('/centerSys/navigation/deleteMenu', {
- params:{menuId}
+export const delData = (menuId: number) => {
+ return request('/centerSys/navigation/deleteMenu', {
+ params: { menuId },
//获取功能字典
-export type MenuRelaActDicItemType = {
- code:string;
- value:string;
+export type MenuRelaActDicItemType = {
export const getMenuRelaActDic = () => {
- return request<MenuRelaActDicItemType[]>('/centerSys/navigation/getFunctionDict', {
+ return request<MenuRelaActDicItemType[]>('/centerSys/navigation/getFunctionDict', {
//保存功能字典
-export const updateFuncDic = (data:{
- function:{code:string;name:string}[]
- return request('/centerSys/navigation/addFunction', {
+export const updateFuncDic = (data: { menuId: number; function: { code: string; name: string }[] }) => {
+ return request('/centerSys/navigation/addFunction', {
* @Date: 2022-01-11 09:43:18
- * @LastEditTime: 2023-03-24 12:28:42
+ * @LastEditTime: 2024-04-01 14:07:34
* @FilePath: /KC-MiddlePlatform/src/pages/platform/userManage/index.tsx
@@ -42,8 +42,7 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();
const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
- const [dirData,set_dirData] = useState<UserRelaSeletDataType[]>([]);
+ const [dirData, set_dirData] = useState<UserRelaSeletDataType[]>([]);
const columns: ProColumns<TableListItem>[] = [
@@ -72,8 +71,8 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
title: '在职状态',
dataIndex: 'isOnService',
valueEnum: {
- 1: { text: '否', status: 'Default' },
- 0: { text: '是', status: 'Success' },
+ 0: { text: '否', status: 'Default' },
+ 1: { text: '是', status: 'Success' },
@@ -105,15 +104,13 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
const getUserData = async (params: TableRequestParamsType) => {
- const { current = 1, pageSize = 10, name = undefined, account = undefined,departmentId=undefined} = params;
+ const { current = 1, pageSize = 10, name = undefined, account = undefined, departmentId = undefined } = params;
const resp = await getUsers({
current,
pageSize,
keyword: name ? name : account,
- departmentId
+ departmentId,
//获取万最新数据取消重置reload
@@ -189,62 +186,56 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
const data = await getUserRelaSeletData(key);
const tableDataSearchHandle = (paramName: string) => {
set_tableDataFilterParams({
...tableDataFilterParams,
const importData = (name: string) => {
title={`导入${name}数据`}
- <span key="3">导入</span>
- onFinish={async (values:any) => {
- const { importFile: { fileList } } = values;
+ trigger={<span key="3">导入</span>}
+ onFinish={async (values: any) => {
+ importFile: { fileList },
+ } = values;
let formData = new FormData();
+ console.log({ values });
formData.append('file', fileList[0].originFileObj);
- dispatch({
- type: 'userManageModel/importUsers',
- payload: formData,
+ dispatch({
+ type: 'userManageModel/importUsers',
+ payload: formData,
<FormItem name={'importFile'}>
<KCUpload downloadTemplateFile={() => getUserTemplateHandle()} />
</FormItem>
- let defaultValue = dataArr.filter(t => t.defaultValue == 1);
dataArr.sort((prev: UserRelaSeletDataListType, next: UserRelaSeletDataListType) => {
@@ -252,77 +243,80 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
- list: dataArr.map(t =>{
- return ({ label: t.value, value: t.code })
+ list: dataArr.map((t) => {
+ return { label: t.name, value: t.code };
defaultvalue: '',
- list: []
// console.log({state});
<div className="UserManage">
- <ActModal {...state} dispatch={dispatch} />
+ <ActModal {...state} dispatch={dispatch} />
- <div className='filterItem' style={{ marginRight: 16}}>
- <span className='label'>科室:</span>
+ <div className="filterItem" style={{ marginRight: 16 }}>
+ <span className="label">科室:</span>
<ProFormSelect
- name="departmentId"
- style={{width:160}}
- const resp = await getDepartmentData({pageSize:1000});
- return resp.list.map(a=>({label:a.name,value:a.id}))
- showSearch:true,
- onChange:(val) => {
- departmentId:val
+ name="departmentId"
+ const resp = await getDepartmentData({ pageSize: 1000 });
+ return resp.list.map((a) => ({ label: a.name, value: a.id }));
+ showSearch: true,
+ onChange: (val) => {
+ departmentId: val,
- <KCInput placeholder={'请输入姓名/工号'} style={{ width: 160 }} search allowClear
+ placeholder={'请输入姓名/工号'}
onChange={(e) => {
set_tableDataSearchKeywords(e.target.value);
if (e.target.value.length == 0) {
onSearch={() => tableDataSearchHandle('name')}
{importData('员工')}
- <span className='add' onClick={addUserHandle}>新增</span>
+ <span className="add" onClick={addUserHandle}>
+ 新增
@@ -334,8 +328,8 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
params={tableDataFilterParams}
newVer
expandable={{
- expandedRowRender: record => (
- <div className='userExpandInfo'>
+ expandedRowRender: (record) => (
+ <div className="userExpandInfo">
<span>进院时间:{record.entryTime}</span>
<span>手机号:{record.phoneNumber}</span>
<span>所学专业:{record.major}</span>
@@ -375,12 +369,10 @@ const UserManage: FC<PageProps> = ({ userManageModel: state, dispatch }) => {
-export default connect(
- ({ userManageModel, loading }: { userManageModel: userManageModelState; loading: Loading }) => {
- // console.log({userManageModel});
- userManageModel,
- loading: loading.models.userManageModel,
-)(UserManage);
+export default connect(({ userManageModel, loading }: { userManageModel: userManageModelState; loading: Loading }) => {
+ // console.log({userManageModel});
+ userManageModel,
+ loading: loading.models.userManageModel,
+})(UserManage);
- * @LastEditTime: 2023-03-24 12:31:46
+ * @LastEditTime: 2023-12-14 14:29:22
@@ -34,13 +34,7 @@ interface ActModalProps extends userManageModelState {
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
- currentEditUser,
+const ActModal: React.FC<ActModalProps> = ({ dispatch, isShowModal, tableAct, currentEditUser }) => {
const [avatarUrl, setAvatarUrl] = useState<string>('');
const [loadAvatar, setLoadAvatar] = useState(false);
@@ -51,19 +45,18 @@ const ActModal: React.FC<ActModalProps> = ({
name: 'file',
maxCount: 1,
showUploadList: false,
- onChange(info: { file: any; fileList: any; }) {
+ onChange(info: { file: any; fileList: any }) {
setLoadAvatar(true);
if (info.file.status !== 'uploading') {
// console.log(info.file, info.fileList);
const reader = new FileReader();
- reader.readAsDataURL(info.file.originFileObj);//读取图像文件 result 为 DataURL, DataURL 可直接 赋值给 img.src
+ reader.readAsDataURL(info.file.originFileObj); //读取图像文件 result 为 DataURL, DataURL 可直接 赋值给 img.src
reader.onload = function (event) {
if (event.target && typeof event.target.result == 'string') {
- setAvatarUrl(event.target.result);//base64
+ setAvatarUrl(event.target.result); //base64
if (info.file.status === 'done') {
setLoadAvatar(false);
@@ -71,7 +64,7 @@ const ActModal: React.FC<ActModalProps> = ({
message.error(`${info.file.name} 上传失败!`);
@@ -85,6 +78,7 @@ const ActModal: React.FC<ActModalProps> = ({
@@ -105,21 +99,19 @@ const ActModal: React.FC<ActModalProps> = ({
@@ -127,17 +119,17 @@ const ActModal: React.FC<ActModalProps> = ({
- list: dataArr.map(t => {
const uploadButton = (
<div>
@@ -148,308 +140,303 @@ const ActModal: React.FC<ActModalProps> = ({
width={720}
- layout='vertical'
- className='ProfileModal'
+ layout="vertical"
+ className="ProfileModal"
initialValues={
- tableAct == TableActType.EDIT ? { ...currentEditUser } : {
- //设置当新增时的默认值
- major: (setSelectorData('PROFESSIONAL_TYPE')).defaultvalue,
- jobTitle: (setSelectorData('POSITION_TYPE')).defaultvalue,
- doctorLevel: (setSelectorData('PHYSICIAN_TYPE')).defaultvalue,
- practiceSubject: setSelectorData('PROCESSIONAL_SUBJECTS_TYPE').defaultvalue,
- title: setSelectorData('TITLE_TYPE').defaultvalue,
- practiceCate: setSelectorData('JOB_TYPE').defaultvalue,
- practiceStatus: setSelectorData('PROFESSIONAL_STATUS_TYPE').defaultvalue,
- position: setSelectorData('POSITION').defaultvalue,
- departmentId: setSelectorData('PRACTICE_DEPARTMENT_TYPE').defaultvalue,
- userCate: setSelectorData('PERSONNEL_CATEGORY').defaultvalue,
- degree: setSelectorData('EDUCATION').defaultvalue,
+ ? { ...currentEditUser, departmentId: { label: currentEditUser?.departmentName, value: currentEditUser?.departmentId } }
+ //设置当新增时的默认值
+ major: setSelectorData('PROFESSIONAL_TYPE').defaultvalue,
+ jobTitle: setSelectorData('POSITION_TYPE').defaultvalue,
+ doctorLevel: setSelectorData('PHYSICIAN_TYPE').defaultvalue,
+ practiceSubject: setSelectorData('PROCESSIONAL_SUBJECTS_TYPE').defaultvalue,
+ title: setSelectorData('TITLE_TYPE').defaultvalue,
+ practiceCate: setSelectorData('JOB_TYPE').defaultvalue,
+ practiceStatus: setSelectorData('PROFESSIONAL_STATUS_TYPE').defaultvalue,
+ position: setSelectorData('POSITION').defaultvalue,
+ departmentId: setSelectorData('PRACTICE_DEPARTMENT_TYPE').defaultvalue,
+ userCate: setSelectorData('PERSONNEL_CATEGORY').defaultvalue,
+ degree: setSelectorData('EDUCATION').defaultvalue,
title={tableAct == TableActType.EDIT ? '编辑用户' : '新增用户'}
// labelCol={{ span: 5 }}
// wrapperCol={{ span:8 }}
- onFinish={async (data) => onFinishHandle(data)}
+ onFinish={async (data) => onFinishHandle({ ...data, departmentId: data.departmentId.value, departmentName: data.departmentId.label })}
+ {dirData ? (
+ <div className="wraper">
+ <span style={{ fontSize: 14, color: '#17181A', marginBottom: 3, display: 'block' }}>照片:</span>
+ <div className="avatarContainer">
+ <Upload
+ // name="avatar"
+ listType="picture-card"
+ showUploadList={false}
+ {...props}
+ {avatarUrl ? <img src={avatarUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
+ </Upload>
- dirData ? (
- <span style={{ fontSize: 14, color: '#17181A', marginBottom: 3, display: 'block' }}>照片:</span>
- <div className='avatarContainer'>
- <Upload
- // name="avatar"
- listType="picture-card"
- showUploadList={false}
- {...props}
- {avatarUrl ? <img src={avatarUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
- </Upload>
- <div className='formItem'>
- name="isOnService"
- label='在职:'
- rules={[{ required: true, message: '请选择专业!' }]}
- name="position"
- label="岗位:"
- options={setSelectorData('POSITION').list}
- rules={[{ required: true, message: '请选择!' }]}
+ <div className="formItem">
+ name="isOnService"
+ label="在职:"
+ rules={[{ required: true, message: '请选择专业!' }]}
+ name="position"
+ label="岗位:"
+ options={setSelectorData('POSITION').list}
+ rules={[{ required: true, message: '请选择!' }]}
+ <ProFormText name="name" label="姓名:" placeholder="请输入" rules={[{ required: true, message: '请输入姓名!' }]} />
+ <ProFormText name="account" label="工号:" placeholder="请输入" rules={[{ required: true, message: '请输入工号!' }]} />
+ name="gender"
+ label="性别:"
+ { label: '男', value: 1 },
+ { label: '女', value: 2 },
+ rules={[{ required: true, message: '请选择性别!' }]}
+ label="所属院区:"
+ name="hospId"
+ if (hospList) {
+ return hospList.map((t) => ({
+ label: t.name,
+ value: t.id,
+ message: '请选择院区!',
+ label="科室:"
+ return resp.list.map((a) => ({ label: a.name, value: a.code }));
+ <ProFormSelect name="userCate" label="人员类别:" fieldProps={{ showSearch: true }} options={setSelectorData('PERSONNEL_CATEGORY').list} placeholder="请选择" />
+ <ProFormDateTimePicker name="entryTime" label="入职时间" placeholder={'请选择日期'} rules={[{ required: true, message: '请选择日期!' }]} />
+ name="title"
+ label="职称:"
+ options={setSelectorData('TITLE_TYPE').list}
+ rules={[{ required: true, message: '请选择职称!' }]}
+ name="jobTitle"
+ label="职务:"
+ options={setSelectorData('POSITION_TYPE').list}
+ rules={[{ required: true, message: '请选择职务!' }]}
+ <ProFormDependency name={['isOnService']}>
+ {({ isOnService }) => (
+ <ProFormDateTimePicker disabled={isOnService == 0} label="离职日期:" name="outTime" placeholder={'请选择离职时间'} />
+ <ProFormText name="graduateSchool" label="毕业院校:" placeholder="请输入" rules={[{ required: false, message: '请输入院校!' }]} />
+ name="degree"
+ label="学历:"
+ options={setSelectorData('EDUCATION').list}
+ rules={[{ required: true, message: '请选择学历!' }]}
+ name="major"
+ label="所学专业:"
+ options={setSelectorData('PROFESSIONAL_TYPE').list}
- <ProFormText name="name" label="姓名:" placeholder="请输入" rules={[{ required: true, message: '请输入姓名!' }]} />
- <ProFormText name="account" label="工号:" placeholder="请输入" rules={[{ required: true, message: '请输入工号!' }]} />
- name="gender"
- label="性别:"
- { label: '男', value: 1 },
- { label: '女', value: 2 },
- rules={[{ required: true, message: '请选择性别!' }]}
- label="所属院区:"
- const hospList = await getShareHospList();
- if (hospList) {
- label: t.name,
- value: t.id,
- message: '请选择院区!',
- label="科室:"
- showSearch:true
- name="userCate"
- label="人员类别:"
- options={setSelectorData('PERSONNEL_CATEGORY').list}
- <ProFormDateTimePicker name="entryTime" label="入职时间" placeholder={'请选择日期'} rules={[{ required: true, message: '请选择日期!' }]} />
- name="title"
- label="职称:"
- options={setSelectorData('TITLE_TYPE').list}
- rules={[{ required: true, message: '请选择职称!' }]}
- name="jobTitle"
- label="职务:"
- options={setSelectorData('POSITION_TYPE').list}
- rules={[{ required: true, message: '请选择职务!' }]}
- <ProFormDependency name={['isOnService']}>
- {({ isOnService }) => (
- <ProFormDateTimePicker disabled={isOnService == 0} label='离职日期:' name="outTime" placeholder={'请选择离职时间'} />
- <ProFormText name="graduateSchool" label="毕业院校:" placeholder="请输入" rules={[{ required: false, message: '请输入院校!' }]} />
- name="degree"
- label="学历:"
- options={setSelectorData('EDUCATION').list}
- rules={[{ required: true, message: '请选择学历!' }]}
- name="major"
- label="所学专业:"
- options={setSelectorData('PROFESSIONAL_TYPE').list}
- <div className='formItem' >
- <ProFormText name="idCardNum" label="身份证号:" placeholder="请输入" rules={[{ required:false, message: '请选择!' }]} />
- <ProFormText name="phoneNumber" label="手机号:" placeholder="请输入" />
- <ProFormDependency name={['userCate']}>
- {({ userCate }) => (userCate == 6 || userCate == 5) && (
- <div className='formItem' style={{ position: 'relative', left: -175 }}>
- name="practiceCate"
- label="执业类别:"
- options={setSelectorData('JOB_TYPE').list}
+ <ProFormText name="idCardNum" label="身份证号:" placeholder="请输入" rules={[{ required: false, message: '请选择!' }]} />
+ <ProFormText name="phoneNumber" label="手机号:" placeholder="请输入" />
+ <ProFormDependency name={['userCate']}>
+ {({ userCate }) =>
+ (userCate == 6 || userCate == 5) && (
+ <div className="formItem" style={{ position: 'relative', left: -175 }}>
+ <ProFormSelect name="practiceCate" label="执业类别:" fieldProps={{ showSearch: true }} options={setSelectorData('JOB_TYPE').list} placeholder="请选择" />
name="practiceSubject"
label="执业科目:"
options={setSelectorData('PROCESSIONAL_SUBJECTS_TYPE').list}
placeholder="请选择"
rules={[{ required: true, message: '请选择!' }]}
<ProFormText name="practiceCertificateNo" label="执业证号:" placeholder="请输入" rules={[{ required: true, message: '请选择!' }]} />
name="practiceStatus"
label="执业状态:"
options={setSelectorData('PROFESSIONAL_STATUS_TYPE').list}
<ProFormText name="qualificationCertificateNo" label="资格证号:" placeholder="请输入" rules={[{ required: true, message: '请输入!' }]} />
- <div className='formItem' style={{ position: 'relative', top: -62 }}>
+ <div className="formItem" style={{ position: 'relative', top: -62 }}>
name="doctorLevel"
label="医师:"
options={setSelectorData('PHYSICIAN_TYPE').list}
- <div style={{ display: 'flex', flexDirection: 'row', width: '100%' }}>
- label='备注'
- placeholder="请输入备注"
- ) : ''
+ <div style={{ display: 'flex', flexDirection: 'row', width: '100%' }}>
+ <ProFormTextArea label="备注" name="remark" width={688} placeholder="请输入备注" />
+ ''
@@ -1,22 +1,16 @@
- * @LastEditTime: 2023-03-20 13:29:04
+ * @LastEditTime: 2024-04-01 11:27:15
import { Effect, ImmerReducer, Reducer, Subscription } from 'umi';
-import {
- addUsers,
- delUsers,
- editUsers,
- getUsertemplate,
- importUserData,
- resetUserPwd,
-} from '@/service/user';
+import { addUsers, delUsers, editUsers, getUsertemplate, importUserData, resetUserPwd } from '@/service/user';
import { TableListItem } from './typings';
+import axios from 'axios';
export enum TableActType {
NOACT,
@@ -83,12 +77,10 @@ const userManageModel: userManageModelType = {
*resetUserPwd({ payload }) {
yield resetUserPwd({ userId: payload.id });
- *postEditUserData({ payload }:any, { call, put, select }:any) {
- const currentEditUserOld = yield select(
- ({ userManageModel: state }: { userManageModel: userManageModelState }) => {
- return state.currentEditUser;
+ *postEditUserData({ payload }: any, { call, put, select }: any) {
+ const currentEditUserOld = yield select(({ userManageModel: state }: { userManageModel: userManageModelState }) => {
+ return state.currentEditUser;
yield editUsers({ ...currentEditUserOld, ...payload });
@@ -104,15 +96,37 @@ const userManageModel: userManageModelType = {
*getUserTemplateReq() {
- const url = yield getUsertemplate();
- if(url){
- window.open(url);
+ let path = '/gateway/centerSys/user/exportUserTemplate';
+ const { token = '' } = JSON.parse(userData as string);
+ axios({
+ method: 'get',
+ url: path,
+ responseType: 'blob',
+ headers: { token },
+ }).then(function (response) {
+ //console.log({ 'chunk': response });
+ const filename = decodeURI(response.headers['content-disposition']);
+ const objectUrl = URL.createObjectURL(
+ new Blob([response.data], {
+ type: 'application/vnd.ms-excel',
+ const link = document.createElement('a');
+ // 设置导出的文件名称
+ link.download = `${filename}` + '.xls';
+ link.style.display = 'none';
+ link.href = objectUrl;
+ link.click();
+ document.body.appendChild(link);
*importUsers({ payload }, { call, put, select }) {
- const formData: any = new FormData();
- formData.append('file', payload);
- yield importUserData(formData);
+ // const formData: any = new FormData();
+ // formData.append('file', payload);
+ yield importUserData(payload);
type: 'reloadTable',
payload: true,
- * @LastEditTime: 2022-01-13 11:43:54
+ * @LastEditTime: 2023-04-13 11:06:48
@@ -15,6 +15,8 @@ export type TableListItem = {
phoneNum: number;
idCardNum: number;
isOnService: number;
+ departmentId:string;
+ [key:string]:any