3 Commit-ok 8d0c474498 ... e818a03f95

Szerző SHA1 Üzenet Dátum
  zhaojing e818a03f95 fix:修改租户信息 1 éve
  zhaojing 736215ab87 fix:人员管理 解决冲突 1 éve
  zhaojing a7aa812234 fIx:人员管理的bug修改 1 éve

+ 10 - 19
src/app.tsx

@@ -1,6 +1,6 @@
 import { PageLoading } from '@ant-design/pro-layout';
 import { history, useModel } from 'umi';
-import UserStorage from '@/config/sagacare/sagacare_user';
+import { queryTenantData } from '@/services/sagacare_service/member';
 
 /** 获取用户信息比较慢的时候会展示一个 loading */
 export const initialStateConfig = {
@@ -13,7 +13,7 @@ export const initialStateConfig = {
 export async function getInitialState(): Promise<{
   projectId: String;
   currentUser?: API.CurrentUser;
-  fetchUser?: () => Promise<API.CurrentUser | undefined>;
+  companyConfig?: any;
   //fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
 }> {
   const { location } = history;
@@ -27,40 +27,31 @@ export async function getInitialState(): Promise<{
   //debugger;
   let currentUser = {
     appId: 'wxda2ef261ac3cca32',
-    companyId: '17fe48afcdde4d6797583c6d6270a035', // 'ff80c708fe72446eb790b764c3a7b66b',
+    companyId: '17fe48afcdde4d6797583c6d6270a035', // ff80c708fe72446eb790b764c3a7b66b,
     loginType: 'app',
     manageUserType: 3,
     name: '赵静',
     openId: 'oDcGY5Qq3Vk-7WKTNsn-lLGNT118',
     phone: '13810794283',
-    projectId: 'Pj1101080259', //'Pj1101099999',
+    projectId: 'Pj1101080259', //  Pj1101099999
     userId: 'db445a9cd7be4341a14448928014605c',
   };
-  let projectId = 'Pj1101080259'; // 'Pj1101099999';
+  let projectId = 'Pj1101080259'; //  Pj1101099999
   if (location.pathname.indexOf('login') == -1 && token) {
     var localUser = localStorage.getItem('user') || '';
     currentUser = JSON.parse(localUser);
     projectId = currentUser?.projectId;
   }
-
-  if (projectId == 'Pj3301100002') {
-    //之江项目 验证token
-    // currentUser = await fetchUser();
-  } else {
-    //非之江项目
-    let tempUser = {
-      name: '行政测试',
-      phone: '17611228068',
-      id: '9a1ecfbacb6b4f249bf2dd3ec7793ead',
-    };
-
-    var userObj = UserStorage.getInstance();
-    userObj.setUser(tempUser);
+  let companyConfig = {};
+  if (currentUser.userId) {
+    const res = await queryTenantData(currentUser);
+    companyConfig = res.data;
   }
 
   return {
     projectId,
     currentUser,
+    companyConfig,
   };
 }
 

+ 23 - 3
src/assets/icons/sagacare/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 3184967 */
-  src: url('iconfont.woff2?t=1675837581887') format('woff2'),
-       url('iconfont.woff?t=1675837581887') format('woff'),
-       url('iconfont.ttf?t=1675837581887') format('truetype');
+  src: url('iconfont.woff2?t=1695198155229') format('woff2'),
+       url('iconfont.woff?t=1695198155229') format('woff'),
+       url('iconfont.ttf?t=1695198155229') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,26 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-managemember:before {
+  content: "\e641";
+}
+
+.icon-managecancel:before {
+  content: "\e640";
+}
+
+.icon-manageimport:before {
+  content: "\e63f";
+}
+
+.icon-managefloorHeating:before {
+  content: "\e63e";
+}
+
+.icon-managecalendar:before {
+  content: "\e63d";
+}
+
 .icon-managesocket:before {
   content: "\e637";
 }

+ 0 - 296
src/assets/icons/sagacare/iconfont.json

@@ -1,296 +0,0 @@
-{
-  "id": "3184967",
-  "name": "managecontrol",
-  "font_family": "iconfont",
-  "css_prefix_text": "icon-manage",
-  "description": "行政管理所用图片",
-  "glyphs": [
-    {
-      "icon_id": "34017963",
-      "name": "插座-白色",
-      "font_class": "socket",
-      "unicode": "e637",
-      "unicode_decimal": 58935
-    },
-    {
-      "icon_id": "31441833",
-      "name": "youren",
-      "font_class": "youren",
-      "unicode": "e630",
-      "unicode_decimal": 58928
-    },
-    {
-      "icon_id": "31440631",
-      "name": "wuren",
-      "font_class": "wuren",
-      "unicode": "e62f",
-      "unicode_decimal": 58927
-    },
-    {
-      "icon_id": "29802519",
-      "name": "person",
-      "font_class": "person",
-      "unicode": "e62d",
-      "unicode_decimal": 58925
-    },
-    {
-      "icon_id": "29802295",
-      "name": "introduce",
-      "font_class": "introduce",
-      "unicode": "e62b",
-      "unicode_decimal": 58923
-    },
-    {
-      "icon_id": "28976686",
-      "name": "cloth",
-      "font_class": "cloth",
-      "unicode": "e62a",
-      "unicode_decimal": 58922
-    },
-    {
-      "icon_id": "28976672",
-      "name": "swim",
-      "font_class": "swim",
-      "unicode": "e629",
-      "unicode_decimal": 58921
-    },
-    {
-      "icon_id": "28976650",
-      "name": "book",
-      "font_class": "book",
-      "unicode": "e628",
-      "unicode_decimal": 58920
-    },
-    {
-      "icon_id": "28976637",
-      "name": "experiment",
-      "font_class": "experiment",
-      "unicode": "e627",
-      "unicode_decimal": 58919
-    },
-    {
-      "icon_id": "28976620",
-      "name": "reception",
-      "font_class": "reception",
-      "unicode": "e626",
-      "unicode_decimal": 58918
-    },
-    {
-      "icon_id": "28976599",
-      "name": "activity",
-      "font_class": "activity",
-      "unicode": "e625",
-      "unicode_decimal": 58917
-    },
-    {
-      "icon_id": "28976561",
-      "name": "control",
-      "font_class": "control",
-      "unicode": "e624",
-      "unicode_decimal": 58916
-    },
-    {
-      "icon_id": "28975871",
-      "name": "体育课sport 2",
-      "font_class": "sport",
-      "unicode": "e623",
-      "unicode_decimal": 58915
-    },
-    {
-      "icon_id": "28973376",
-      "name": "公共public",
-      "font_class": "public",
-      "unicode": "e622",
-      "unicode_decimal": 58914
-    },
-    {
-      "icon_id": "28254404",
-      "name": "类型=repair, 线条=400device",
-      "font_class": "device",
-      "unicode": "e620",
-      "unicode_decimal": 58912
-    },
-    {
-      "icon_id": "28254396",
-      "name": "类型=lift, 线条=400elevator",
-      "font_class": "lift",
-      "unicode": "e61f",
-      "unicode_decimal": 58911
-    },
-    {
-      "icon_id": "28254360",
-      "name": "类型=cutlery, 线条=400dining",
-      "font_class": "dining",
-      "unicode": "e61e",
-      "unicode_decimal": 58910
-    },
-    {
-      "icon_id": "28253957",
-      "name": "类型=restroom, 线条=400washroom",
-      "font_class": "washroom",
-      "unicode": "e61c",
-      "unicode_decimal": 58908
-    },
-    {
-      "icon_id": "28037752",
-      "name": "TUI-iconfontreduce",
-      "font_class": "reduce",
-      "unicode": "e61b",
-      "unicode_decimal": 58907
-    },
-    {
-      "icon_id": "28037745",
-      "name": "TUI-iconfontzoom",
-      "font_class": "zoom",
-      "unicode": "e61a",
-      "unicode_decimal": 58906
-    },
-    {
-      "icon_id": "27977233",
-      "name": "TUI-iconfontenviroment",
-      "font_class": "environment",
-      "unicode": "e619",
-      "unicode_decimal": 58905
-    },
-    {
-      "icon_id": "27977222",
-      "name": "TUI-iconfontdevice",
-      "font_class": "equipment",
-      "unicode": "e618",
-      "unicode_decimal": 58904
-    },
-    {
-      "icon_id": "27977163",
-      "name": "TUI-iconfonttime",
-      "font_class": "runtime",
-      "unicode": "e617",
-      "unicode_decimal": 58903
-    },
-    {
-      "icon_id": "27960522",
-      "name": "TUI-iconfontnotify",
-      "font_class": "notify",
-      "unicode": "e615",
-      "unicode_decimal": 58901
-    },
-    {
-      "icon_id": "27790782",
-      "name": "work",
-      "font_class": "work",
-      "unicode": "e614",
-      "unicode_decimal": 58900
-    },
-    {
-      "icon_id": "27710574",
-      "name": "TUI-iconfonthover",
-      "font_class": "hover",
-      "unicode": "e613",
-      "unicode_decimal": 58899
-    },
-    {
-      "icon_id": "27693456",
-      "name": "light",
-      "font_class": "light",
-      "unicode": "e611",
-      "unicode_decimal": 58897
-    },
-    {
-      "icon_id": "27693440",
-      "name": "curtain",
-      "font_class": "curtain",
-      "unicode": "e610",
-      "unicode_decimal": 58896
-    },
-    {
-      "icon_id": "27693407",
-      "name": "air",
-      "font_class": "airConditioner",
-      "unicode": "e60f",
-      "unicode_decimal": 58895
-    },
-    {
-      "icon_id": "27693388",
-      "name": "walk",
-      "font_class": "walk",
-      "unicode": "e60e",
-      "unicode_decimal": 58894
-    },
-    {
-      "icon_id": "27693355",
-      "name": "stair",
-      "font_class": "stair",
-      "unicode": "e60d",
-      "unicode_decimal": 58893
-    },
-    {
-      "icon_id": "27693304",
-      "name": "Iconrest",
-      "font_class": "rest",
-      "unicode": "e60c",
-      "unicode_decimal": 58892
-    },
-    {
-      "icon_id": "27693282",
-      "name": "office",
-      "font_class": "office",
-      "unicode": "e60b",
-      "unicode_decimal": 58891
-    },
-    {
-      "icon_id": "27693270",
-      "name": "Iconmeeting",
-      "font_class": "meeting",
-      "unicode": "e60a",
-      "unicode_decimal": 58890
-    },
-    {
-      "icon_id": "27693217",
-      "name": "letter",
-      "font_class": "letter",
-      "unicode": "e609",
-      "unicode_decimal": 58889
-    },
-    {
-      "icon_id": "27645303",
-      "name": "document",
-      "font_class": "document",
-      "unicode": "e608",
-      "unicode_decimal": 58888
-    },
-    {
-      "icon_id": "27093212",
-      "name": "类型=warning, 线条=400",
-      "font_class": "warning",
-      "unicode": "ea51",
-      "unicode_decimal": 59985
-    },
-    {
-      "icon_id": "27639602",
-      "name": "closeall",
-      "font_class": "closeall",
-      "unicode": "e607",
-      "unicode_decimal": 58887
-    },
-    {
-      "icon_id": "27635623",
-      "name": "search",
-      "font_class": "search",
-      "unicode": "e606",
-      "unicode_decimal": 58886
-    },
-    {
-      "icon_id": "27635605",
-      "name": "close",
-      "font_class": "close",
-      "unicode": "e605",
-      "unicode_decimal": 58885
-    },
-    {
-      "icon_id": "27635439",
-      "name": "backward",
-      "font_class": "backward",
-      "unicode": "e604",
-      "unicode_decimal": 58884
-    }
-  ]
-}

BIN
src/assets/icons/sagacare/iconfont.ttf


BIN
src/assets/icons/sagacare/iconfont.woff


BIN
src/assets/icons/sagacare/iconfont.woff2


+ 20 - 20
src/hooks/useMenuList.ts

@@ -26,26 +26,26 @@ export default function () {
         ],
       },
 
-      {
-        title: '运营服务',
-        menus: [
-          {
-            id: 'environment',
-            title: '环境信息',
-            icon: homeImgMap.environment,
-          },
-          {
-            id: 'equipment',
-            title: '设备管理',
-            icon: homeImgMap.equipment,
-          },
-          {
-            id: 'runtime',
-            title: '运行时间',
-            icon: homeImgMap.runtime,
-          },
-        ],
-      },
+      // {
+      //   title: '运营服务',
+      //   menus: [
+      //     // {
+      //     //   id: 'environment',
+      //     //   title: '环境信息',
+      //     //   icon: homeImgMap.environment,
+      //     // },
+      //     {
+      //       id: 'equipment',
+      //       title: '设备管理',
+      //       icon: homeImgMap.equipment,
+      //     },
+      //     // {
+      //     //   id: 'runtime',
+      //     //   title: '运行时间',
+      //     //   icon: homeImgMap.runtime,
+      //     // },
+      //   ],
+      // },
     ]);
     // setMenuList([
     //   // { name: '环境信息', id: 'environment' },

+ 2 - 1
src/layouts/index.jsx

@@ -103,7 +103,8 @@ export default (props) => {
               history.push('/home');
             }}
           >
-            之江项目
+            <span className={styles.projectName}>{initialState?.companyConfig?.projectName}</span>
+            <span>{initialState?.companyConfig?.companyName}</span>
           </span>
           <Head></Head>
         </div>

+ 6 - 0
src/layouts/index.less

@@ -34,10 +34,16 @@
     display: flex;
     align-items: baseline;
     .project {
+      display: flex;
+      flex-direction: column;
       color: #000;
       font-weight: 600;
       font-size: 24px;
       cursor: pointer;
+      .projectName {
+        color: #c4c4c4;
+        font-size: 14px;
+      }
     }
   }
   .right {

+ 4 - 0
src/pages/Home/index.less

@@ -3,6 +3,10 @@
   justify-content: space-between;
   .left {
     width: 500px;
+    .userName {
+      color: #000000;
+      font-size: 20px;
+    }
   }
   .right {
     width: 400px;

+ 5 - 1
src/pages/Home/index.tsx

@@ -7,9 +7,13 @@ import cx from 'classnames';
 import NavMenu from '@/sagacare_components/navMenu';
 
 const Runtime: React.FC = () => {
+  const { initialState } = useModel('@@initialState');
+
   return (
     <div className={styles.homewrap}>
-      <div className={styles.left}></div>
+      <div className={styles.left}>
+        <span className={styles.userName}>你好,{initialState?.companyConfig?.name}</span>
+      </div>
       <div className={styles.right}>
         <NavMenu></NavMenu>
       </div>

+ 86 - 46
src/pages/Member/components/areaTree/index.jsx

@@ -22,7 +22,7 @@ import { ExclamationCircleOutlined } from '@ant-design/icons';
 import moment from 'moment';
 
 const AreaTree = ({
-  checkSign,
+  checkSign, //是否是查看状态
   spaceMap,
   checkedValues,
   radioValue,
@@ -122,64 +122,104 @@ const AreaTree = ({
         allSpacesTemp.push(sitem.spaceId);
         return cnode;
       });
+
       node.children = children;
       treeDataTemp.push(node);
     }
     setAllSpaces(allSpacesTemp);
+    console.log('treeDataTemptreeDataTemp', treeDataTemp);
     setTreeData(treeDataTemp);
   }, [spaceMap]);
 
   const renderNode = (nodeData) => {
     return (
       <div className={styles.treeTitle}>
-        <div style={{ width: 210 - 24 * nodeData.level + 'px' }}> {nodeData.title}</div>
+        <div style={{ width: 210 - 24 * nodeData?.level + 'px' }}> {nodeData?.title}</div>
         <div className={styles.residentSpan}>
           <Radio
-            value={nodeData.key}
             disabled={checkSign == 'check'}
-            // checked={nodeData.radioChecked}
+            value={nodeData.key}
+            checked={nodeData.key == radioValue}
+            onChange={oneRadioChange}
           >
-            {nodeData.key == 'special' ? '不选择' : ''}
+            {nodeData?.key == 'special' ? '不选择' : ''}
           </Radio>
         </div>
         <div className={styles.controlSpan}>
-          <Checkbox disabled={checkSign == 'check'} value={nodeData.key} onChange={onOneChange}>
-            {nodeData.key == 'special' ? '全选' : ''}
+          <Checkbox
+            disabled={checkSign == 'check'}
+            value={nodeData.key}
+            checked={checkedValues.indexOf(nodeData.key) > -1}
+            onChange={oneCheckChange}
+          >
+            {nodeData?.key == 'special' ? '全选' : ''}
           </Checkbox>
         </div>
       </div>
     );
   };
 
-  const onOneChange = (event) => {
-    // debugger;
-    // event.target.value  event.target.checked
+  const oneCheckChange = (event) => {
+    console.log('event.target.value', event.target.value, event.target.checked);
+    var value = event.target.value;
+    var checkCopy = [...checkedValues];
+    if (event.target.checked) {
+      //选中
+      checkCopy.push(value);
+      if (value == 'special') {
+        //全选选中
+        setCheckedValues(allSpaces);
+        return;
+      }
+    } else {
+      checkCopy = checkedValues.filter((item) => {
+        return item != value;
+      });
+      if (value == 'special') {
+        //全选取消
+        setCheckedValues([]);
+        return;
+      }
+    }
+
+    setCheckedValues(checkCopy);
   };
-  const onRadioChange = (event) => {
+  const oneRadioChange = (event) => {
+    console.log('event.target.value', event.target.value, event.target.checked);
     var value = event.target.value;
-    setRadioValue(event.target.value);
+    setRadioValue(value);
+    var checkCopy = [...checkedValues];
     var index = checkedValues.findIndex((ele) => ele === value);
     if (index == -1) {
-      checkedValues.push(value);
+      checkCopy.push(value);
     }
-    setCheckedValues(checkedValues);
-  };
-  const onCheckboxChange = (values) => {
-    debugger;
-    var lastValue = values[values.length - 1];
-    if (lastValue == 'special') {
-      //全选选中
-      setCheckedValues(allSpaces);
-      return;
-    }
-    if (checkedValues.includes('special') && !values.includes('special')) {
-      //全选取消
-      setCheckedValues([]);
-      return;
-    }
-    setCheckedValues(values);
+    setCheckedValues(checkCopy);
   };
 
+  // const onRadioChange = (event) => {
+  //   var value = event.target.value;
+  //   setRadioValue(event.target.value);
+  //   var index = checkedValues.findIndex((ele) => ele === value);
+  //   if (index == -1) {
+  //     checkedValues.push(value);
+  //   }
+  //   setCheckedValues(checkedValues);
+  // };
+  // const onCheckboxChange = (values) => {
+  //   var lastValue = values[values.length - 1];
+  //   if (lastValue == 'special') {
+  //     //全选选中
+  //     setCheckedValues(allSpaces);
+  //     return;
+  //   }
+  //   if (checkedValues.includes('special') && !values.includes('special')) {
+  //     //全选取消
+  //     setCheckedValues([]);
+  //     return;
+  //   }
+  //   setCheckedValues(values);
+  // };
+
   const debounceHandle = (event) => {};
   return (
     <>
@@ -194,23 +234,23 @@ const AreaTree = ({
           <div className={styles.residentSpan}>常驻工区选择</div>
           <div className={styles.controlSpan}>可控工区选择</div>
         </div>
-        <Checkbox.Group onChange={onCheckboxChange} value={checkedValues}>
-          <Radio.Group onChange={onRadioChange} value={radioValue}>
-            <Tree
-              height={310}
-              defaultExpandedKeys={['0-0-0']}
-              selectable={false}
-              treeData={treeData}
-              titleRender={(nodeData) => {
-                if (nodeData.children && nodeData.children.length) {
-                  return <div className={styles.treeTitle}>{nodeData.title}</div>;
-                } else {
-                  return renderNode(nodeData);
-                }
-              }}
-            />
-          </Radio.Group>
-        </Checkbox.Group>
+        {/* <Checkbox.Group onChange={onCheckboxChange} value={checkedValues}>
+          <Radio.Group onChange={onRadioChange} value={radioValue} > */}
+        <Tree
+          height={310}
+          // expandedKeys={['Fl11010802593241ec348ecb4148806b9034c8957454']}
+          selectable={false}
+          treeData={treeData}
+          titleRender={(nodeData) => {
+            if (nodeData?.children && nodeData?.children?.length) {
+              return <div className={styles.treeTitle}>{nodeData?.title}</div>;
+            } else {
+              return renderNode(nodeData || {});
+            }
+          }}
+        />
+        {/* </Radio.Group>
+        </Checkbox.Group> */}
       </div>
     </>
   );

+ 9 - 0
src/pages/Member/components/personModal/index.jsx

@@ -179,6 +179,15 @@ const PersonModal = ({
                 )}
               </div>
             )}
+            <div className={styles.circlePic}>
+              <Icon
+                type="member"
+                style={{
+                  color: '#fff',
+                  fontSize: '35px',
+                }}
+              ></Icon>
+            </div>
           </div>
           {!invalidSign && (
             <>

+ 14 - 0
src/pages/Member/components/personModal/index.less

@@ -35,6 +35,20 @@
         margin-right: 18px;
       }
     }
+    .circlePic {
+      position: absolute;
+      top: 86px;
+      right: 0;
+      left: 0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 68px;
+      height: 68px;
+      margin: auto;
+      background: #ffe823;
+      border-radius: 100%;
+    }
   }
 
   .close {

+ 40 - 11
src/pages/Member/index.tsx

@@ -8,10 +8,11 @@ import Search from '@/sagacare_components/Search';
 import Table from '@/sagacare_components/Table';
 import Empty from './components/Empty';
 import PersonModal from './components/personModal';
+import { EllipsisOutlined, InfoCircleOutlined } from '@ant-design/icons';
+import Icon from '@/tenants-ui/SgIcon';
 import ImportModal from './components/StartImport';
 import ImportError from './components/StartImport/ImportError';
 import ImportSuccess from './components/StartImport/ImportSuccess';
-import { EllipsisOutlined } from '@ant-design/icons';
 
 import {
   queryUserList,
@@ -40,6 +41,8 @@ const Member: React.FC = () => {
   const [checkUser, setCheckUser] = useState({}); //查看的人
   const [checkSign, setCheckSign] = useState('add'); // 三种状态 查看 编辑 新增
   const [refreshNum, setRefreshNum] = useState(0); //刷新列表
+  const [showFilterIds, setShowFilterIds] = useState([]);
+
   // const statusArr = {
   //   2: '正常',
   //   3: '待激活',
@@ -60,16 +63,20 @@ const Member: React.FC = () => {
       {
         title: '姓名',
         dataIndex: 'name',
+        width: 140,
+        render: function (content, item, index) {
+          return <div>{content}</div>;
+        },
       },
       {
         title: '类型',
         dataIndex: 'manageUserType',
-        filteredValue: [],
-        single: true,
+        filteredValue: showFilterIds,
+        single: false,
         filters: [
-          { value: '1', label: '普通成员' },
-          { value: '2', label: '临时成员' },
-          { value: '3', label: '管理员' },
+          { value: 1, label: '普通成员' },
+          { value: 2, label: '临时成员' },
+          { value: 3, label: '管理员' },
         ],
         render: function (content, item, index) {
           return <span>{userTpeyArr[content]}</span>;
@@ -206,6 +213,9 @@ const Member: React.FC = () => {
       ],
     };
     setLoading(true);
+    if (showFilterIds.length > 0) {
+      paramObj.criteria = { ...paramObj.criteria, ...{ manageUserType: showFilterIds } };
+    }
 
     queryUserList(paramObj)
       .then((res) => {
@@ -219,7 +229,7 @@ const Member: React.FC = () => {
       .catch((err) => {
         setLoading(false);
       });
-  }, [searchStr, page, sorter, refreshNum]);
+  }, [searchStr, showFilterIds, page, sorter, refreshNum]);
 
   useEffect(() => {
     //查询受控列表
@@ -288,7 +298,10 @@ const Member: React.FC = () => {
             <Search changeSearchStr={setSearchStr} />
             {isSyncOa ? (
               <>
-                <div className={styles.allIn}>已开启OA同步</div>
+                <div className={styles.allIn}>
+                  <InfoCircleOutlined />
+                  已开启OA同步
+                </div>
                 <div
                   className={styles.invalid}
                   onClick={() => {
@@ -304,6 +317,15 @@ const Member: React.FC = () => {
             ) : (
               <>
                 <div className={styles.allIn} onClick={showImport}>
+                  <Icon
+                    className=""
+                    type="import"
+                    style={{
+                      color: '#4D5262',
+                      fontSize: '15px',
+                      marginRight: '6px',
+                    }}
+                  ></Icon>
                   批量导入
                 </div>
                 <div
@@ -312,6 +334,15 @@ const Member: React.FC = () => {
                     goToInvalid();
                   }}
                 >
+                  <Icon
+                    className=""
+                    type="cancel"
+                    style={{
+                      color: '#4D5262',
+                      fontSize: '15px',
+                      marginRight: '6px',
+                    }}
+                  ></Icon>
                   已作废
                 </div>
                 <div className={styles.addButton} onClick={addNewPerson}>
@@ -333,9 +364,7 @@ const Member: React.FC = () => {
           pagination={!!userList.length}
           onFilterChange={(key, options) => {
             debugger;
-            // if (key == 'spaceName' || key == 'tenantName') {
-            //   setShowFilterIds(options);
-            // }
+            setShowFilterIds(options);
           }}
           onRowClick={(record) => {}}
           onSortChange={(col: any, direction: string) => {

+ 16 - 8
src/pages/Member/invalid/index.jsx

@@ -22,14 +22,16 @@ export default (props) => {
   const [sorter, setSorter] = useState({
     updateDate: 'DESC', //'ASC' : 'DESC'
   });
-  const [searchStr, setSearchStr] = useState();
+  const [searchStr, setSearchStr] = useState('');
   const userTpeyArr = {
     1: '普通成员',
     2: '临时成员',
     3: '管理员',
   };
+  const [showFilterIds, setShowFilterIds] = useState([]);
 
   useEffect(() => {
+    debugger;
     var paramObj = {
       criteria: {
         param: searchStr,
@@ -46,6 +48,9 @@ export default (props) => {
       ],
     };
     setLoading(true);
+    if (showFilterIds.length > 0) {
+      paramObj.criteria = { ...paramObj.criteria, ...{ manageUserType: showFilterIds } };
+    }
 
     queryUserList(paramObj)
       .then((res) => {
@@ -59,23 +64,24 @@ export default (props) => {
       .catch((err) => {
         setLoading(false);
       });
-  }, [page, sorter]);
+  }, [searchStr, page, sorter, showFilterIds]);
 
   const getColumns = () => {
     return [
       {
         title: '姓名',
         dataIndex: 'name',
+        width: 140,
       },
       {
         title: '类型',
         dataIndex: 'manageUserType',
-        filteredValue: [],
-        single: true,
+        filteredValue: showFilterIds,
+        single: false,
         filters: [
-          { value: '1', label: '普通成员' },
-          { value: '2', label: '临时成员' },
-          { value: '3', label: '管理员' },
+          { value: 1, label: '普通成员' },
+          { value: 2, label: '临时成员' },
+          { value: 3, label: '管理员' },
         ],
         render: function (content, item, index) {
           return <span>{userTpeyArr[content]}</span>;
@@ -126,7 +132,9 @@ export default (props) => {
           page={page}
           total={total}
           pagination={!!userList.length}
-          onFilterChange={(key, options) => {}}
+          onFilterChange={(key, options) => {
+            setShowFilterIds(options);
+          }}
           onRowClick={(record) => {}}
           onSortChange={(col, direction) => {
             debugger;

+ 2 - 20
src/sagacare_components/Search/index.tsx

@@ -28,26 +28,7 @@ const SearchInput: React.FC<SearchInputProps> = ({ changeSearchStr }) => {
       clearTimeout(ref.current);
     }
 
-    function fake() {
-      setLoading(true);
-      var paramsObj = {
-        criteria: {
-          projectId: projectObj.projectId,
-          localName: {
-            $like: `%${value}%`,
-          },
-        },
-      };
-      //搜索
-      querySpace(paramsObj).then((res) => {
-        var resContent = res.content || [];
-        console.log('setMatch', 'data');
-        setMatchData(resContent);
-        setLoading(false);
-      });
-    }
     function fake2() {
-      debugger;
       changeSearchStr(value);
     }
     //防抖
@@ -59,6 +40,7 @@ const SearchInput: React.FC<SearchInputProps> = ({ changeSearchStr }) => {
   };
   //这是搜索 的下拉列表的搜索
   const handleSearch = (value: string) => {
+    debugger;
     searchQuery(value);
   };
 
@@ -66,6 +48,7 @@ const SearchInput: React.FC<SearchInputProps> = ({ changeSearchStr }) => {
   const handleChange = (sel: string) => {
     setValue(null); //清空输入的值
     setMatchData([]); //清空搜索匹配列表
+    debugger;
     // var filterItem = matchData.filter((item) => {
     //   return item.id == sel;
     // });
@@ -76,7 +59,6 @@ const SearchInput: React.FC<SearchInputProps> = ({ changeSearchStr }) => {
     //console.log('keydown', matchData);
     if (e.code == 'Enter') {
       var resItem = matchData[0] || {};
-      debugger;
     }
   };
 

+ 11 - 2
src/sagacare_components/Table/index.jsx

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
 import { Spin, Popover, Checkbox, Pagination } from 'antd';
 import cx from 'classnames';
 import styles from './index.less';
-import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
+import { ArrowUpOutlined, ArrowDownOutlined, CheckSquareOutlined } from '@ant-design/icons';
 
 export default ({
   pagination = true,
@@ -97,7 +97,16 @@ export default ({
                         }
                       >
                         <span className={cx(styles.filter)}>
-                          <span></span>
+                          {col.filteredValue.length > 0 && (
+                            <span className={cx(styles.fangxing)}>
+                              <span className={cx(styles.circle)}></span>
+                            </span>
+                          )}
+                          {col.filteredValue.length == 0 && (
+                            <span className={cx(styles.filterTitlePic)}>
+                              <CheckSquareOutlined style={{ fontSize: '16px' }} />
+                            </span>
+                          )}
                           <span>{col.title}</span>
                         </span>
                       </Popover>

+ 49 - 22
src/sagacare_components/Table/index.less

@@ -1,19 +1,19 @@
 .table {
   table {
     width: 100%;
+    text-align: left;
     border-collapse: separate;
     border-spacing: 0;
-    text-align: left;
   }
   th {
-    font-weight: normal;
     height: 38px;
     padding: 0 16px;
+    font-weight: normal;
   }
   td {
     padding: 16px;
     background: #fff;
-    border-bottom: 1px solid #EEF1F2;
+    border-bottom: 1px solid #eef1f2;
     &:first-child {
       border-radius: 5px 0 0 5px;
     }
@@ -33,7 +33,7 @@
   tbody tr:hover {
     position: relative;
     z-index: 1;
-    box-shadow: 0 0 2px rgba(0,0,0,.08), 0 3px 10px rgba(0,0,0,.08);
+    box-shadow: 0 0 2px rgba(0, 0, 0, 0.08), 0 3px 10px rgba(0, 0, 0, 0.08);
     td {
       border-bottom: 1px solid transparent;
     }
@@ -44,7 +44,7 @@
   cursor: pointer;
   span {
     margin-left: 10px;
-    color: #C4C4C4;
+    color: #c4c4c4;
   }
   &:hover {
     color: #000;
@@ -56,7 +56,7 @@
 .sortered {
   font-weight: 600;
   span {
-    color: #4D5262;
+    color: #4d5262;
   }
   &:hover {
     span {
@@ -64,27 +64,51 @@
     }
   }
 }
+.fangxing {
+  position: relative;
+  display: inline-block;
+  box-sizing: border-box;
+  width: 16px;
+  height: 16px;
+  margin-right: 8px;
+  border: 1px solid #c4c4c4;
 
+  .circle {
+    position: absolute;
+    top: 3px;
+    left: 3px;
+    display: inline-block;
+    width: 8px;
+    height: 8px;
+    background: #f0da21;
+    border-radius: 100%;
+  }
+}
 .filter {
+  display: flex;
+  align-items: center;
   cursor: pointer;
 }
-
+.filterTitlePic {
+  margin-right: 8px;
+  color: #c4c4c4;
+}
 .filterList {
   margin: -12px -16px;
 }
 
 .filterItem {
   display: flex;
-  height: 45px;
   align-items: center;
+  min-width: 150px;
+  height: 45px;
   padding: 0 20px;
-  cursor: pointer;
   color: #000;
-  min-width: 150px;
+  border-bottom: 1px solid #f6f6f6;
+  cursor: pointer;
   &Value {
     margin-left: 10px;
   }
-  border-bottom: 1px solid #f6f6f6;
   &:hover {
     background: #f0da21;
   }
@@ -98,40 +122,41 @@
 }
 
 .page {
-  margin-top: 15px;
   display: flex;
   justify-content: flex-end;
-  &>div {
+  margin-top: 15px;
+  & > div {
+    padding: 2px 0px;
     background: #fff;
     border-radius: 4px;
-    padding: 2px 0px;
   }
   :global {
     .ant-pagination-item {
       min-width: 28px;
       height: 28px;
-      border: none;
       line-height: 28px;
+      border: none;
       a:hover {
+        color: #4d5262;
         background: #f0f0f0;
-        color: #4D5262;
         outline: 4px solid #f0f0f0;
       }
       &-active {
-        background: #F0DA21;
+        background: #f0da21;
         border-radius: 16px;
         a {
           color: #000;
           &:hover {
-            border-radius: 16px;
             color: #000;
             background: #f0da21;
+            border-radius: 16px;
             outline: none;
           }
         }
       }
     }
-    .ant-pagination-prev, .ant-pagination-next {
+    .ant-pagination-prev,
+    .ant-pagination-next {
       padding: 0 15px;
       transition: none;
       &:hover {
@@ -142,14 +167,16 @@
         color: #656872;
       }
     }
-    .ant-pagination-disabled, .ant-pagination-disabled:hover, .ant-pagination-disabled:focus-visible {
+    .ant-pagination-disabled,
+    .ant-pagination-disabled:hover,
+    .ant-pagination-disabled:focus-visible {
       &:hover {
-        outline: none;
         background: transparent;
+        outline: none;
       }
       a {
         color: #ddd;
       }
     }
   }
-}
+}

+ 18 - 0
src/sagacare_components/navMenu/index.less

@@ -5,6 +5,20 @@
   padding: 0 24px;
   background-color: #fff;
   border-radius: 10px;
+  .tenantNum {
+    display: flex;
+    flex-direction: column;
+    // padding-top: 20px;
+    padding-bottom: 30px;
+    .memberNum {
+      color: #656872;
+      font-size: 30px;
+    }
+    .memberName {
+      color: #c4c4c4;
+      font-size: 14px;
+    }
+  }
   .title {
     display: flex;
     align-items: center;
@@ -15,6 +29,10 @@
     position: absolute;
     top: 42px;
     right: 36px;
+    cursor: pointer;
+  }
+  .exit {
+    cursor: pointer;
   }
   .groupTitle {
     margin: 0 0 13px 10px;

+ 26 - 2
src/sagacare_components/navMenu/index.tsx

@@ -1,5 +1,5 @@
 import React, { useEffect } from 'react';
-import { Row, Col, Image } from 'antd';
+import { Row, Col, Image, Popover } from 'antd';
 import styles from './index.less';
 import Icon from '@/tenants-ui/SgIcon';
 import useMenuList, { menutype } from '@/hooks/useMenuList';
@@ -11,6 +11,8 @@ const NavMenu: React.FC = () => {
   const location = useLocation();
   const { closeMenu } = useModel('controller');
   const { menuList } = useMenuList();
+  const { initialState } = useModel('@@initialState');
+
   //debugger;
   const menuClick = (item: menutype) => {
     closeMenu();
@@ -20,13 +22,35 @@ const NavMenu: React.FC = () => {
   useEffect(() => {
     console.log('location', location);
   }, [location]);
+  const exitClick = () => {
+    localStorage.removeItem('token');
+    history.replace('/login');
+  };
   return (
     <div className={styles.drawerDiv}>
       <div className={styles.title}>
         <img src={logo} style={{ height: 70 }}></img>
       </div>
       <div className={styles.setOut}>
-        <img src={homeImgMap.set} />
+        <Popover
+          placement="leftTop"
+          content={
+            <div
+              style={{ cursor: 'pointer' }}
+              onClick={() => {
+                exitClick();
+              }}
+            >
+              退出
+            </div>
+          }
+        >
+          <img src={homeImgMap.set} />
+        </Popover>
+      </div>
+      <div className={styles.tenantNum}>
+        <span className={styles.memberNum}>{initialState?.companyConfig?.userTotal}</span>
+        <span className={styles.memberName}>员工总数</span>
       </div>
       {menuList?.map((group, fidx) => {
         return (

+ 74 - 43
src/services/sagacare_service/member.js

@@ -19,44 +19,53 @@ function commonParams() {
 
 //新增/修改用户
 export async function saveUserInfo(params, options) {
-  return request(`/xiaojing/controlSpaceUser/saveUser?${commonParams()}`, {
-    method: 'POST',
-    from: 'sagacare',
-    headers: {
-      'Content-Type': 'application/json',
+  return request(
+    `/sgadmin/duoduo-service/setup-service/controlSpaceUser/saveUser?${commonParams()}`,
+    {
+      method: 'POST',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
+      data: params,
     },
-    ...(options || {}),
-    data: params,
-  });
+  );
 }
 //查询用户信息
 export async function queryUserInfo(params, options) {
-  return request(`/xiaojing/controlSpaceUser/queryUser?${commonParams()}`, {
-    method: 'POST',
-    from: 'sagacare',
-    headers: {
-      'Content-Type': 'application/json',
-    },
-    ...(options || {}),
-    data: {
-      ...params,
+  return request(
+    `/sgadmin/duoduo-service/setup-service/controlSpaceUser/queryUser?${commonParams()}`,
+    {
+      method: 'POST',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
+      data: {
+        ...params,
+      },
     },
-  });
+  );
 }
 //用户作废
 export async function deleteUser(params, options) {
-  return request(`/xiaojing/controlSpaceUser/deleteUser?userId=${params.userId}`, {
-    method: 'GET',
-    from: 'sagacare',
-    headers: {
-      'Content-Type': 'application/json',
+  return request(
+    `/sgadmin/duoduo-service/setup-service/controlSpaceUser/deleteUser?userId=${params.userId}`,
+    {
+      method: 'GET',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
     },
-    ...(options || {}),
-  });
+  );
 }
 //用户查询列表
 export async function queryUserList(params, options) {
-  return request(`/xiaojing/controlSpaceUser/query`, {
+  return request(`/sgadmin/duoduo-service/setup-service/controlSpaceUser/query`, {
     method: 'POST',
     from: 'sagacare',
     headers: {
@@ -68,28 +77,34 @@ export async function queryUserList(params, options) {
 }
 //查询受控列表
 export async function queryControlSpaceCompany(params, options) {
-  return request(`/xiaojing/controlSpaceUser/getControlSpaceCompany?${commonParams()}`, {
-    method: 'POST',
-    from: 'sagacare',
-    headers: {
-      'Content-Type': 'application/json',
+  return request(
+    `/sgadmin/duoduo-service/setup-service/controlSpaceUser/getControlSpaceCompany?${commonParams()}`,
+    {
+      method: 'POST',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
+      data: {
+        ...params,
+      },
     },
-    ...(options || {}),
-    data: {
-      ...params,
-    },
-  });
+  );
 }
 //是否oa同步
 export async function queryCompanyOAById(params, options) {
-  return request(`/xiaojing/texCompany/queryCompanyById?companyId=${params.companyId}`, {
-    method: 'GET',
-    from: 'sagacare',
-    headers: {
-      'Content-Type': 'application/json',
+  return request(
+    `/sgadmin/duoduo-service/setup-service/texCompany/queryCompanyById?companyId=${params.companyId}`,
+    {
+      method: 'GET',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
     },
-    ...(options || {}),
-  });
+  );
 }
 
 //获取二维码信息
@@ -104,3 +119,19 @@ export async function qrCodeInfo(params, options) {
     ...(options || {}),
   });
 }
+
+//获取租户信息
+export async function queryTenantData(params, options) {
+  // /sgadmin/duoduo-service/duoduoenv-service/userNew/qrCodeInfo
+  return request(
+    `/xiaojing/user/queryData?userId=${params.userId}&projectId=${params.projectId}&companyId=${params.companyId}`,
+    {
+      method: 'GET',
+      from: 'sagacare',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      ...(options || {}),
+    },
+  );
+}