hejianhao
2025-02-24 ecfb7a62e038c9e50c8cd1d93c2086ddae6f1d50
登录和权限处理
9个文件已修改
317 ■■■■ 已修改文件
management/config/env.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/app.tsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/global.less 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/Login/index.tsx 213 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/Login/service.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/Login/style.less 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/message-notification/components/addAndEdit.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/work-order/banner/components/addAndEdit.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/requestErrorConfig.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/config/env.ts
@@ -1,6 +1,6 @@
export default {
  dev: {
    SERVER_URL: '',
    SERVER_URL: 'http://192.168.110.188:6194',
  },
  test: {
    SERVER_URL: '',
management/src/app.tsx
@@ -6,7 +6,6 @@
import { AvatarDropdown, AvatarName } from './components/RightContent/AvatarDropdown';
import { errorConfig } from './requestErrorConfig';
const loginPath = '/login';
import logo from '../public/logo/logo.png'
import '../public/font.css'
@@ -19,7 +18,18 @@
  permission?: Array<Permissions>;
  loading?: boolean;
}> {
  // 如果不是登录页面,执行
  const { location } = history;
  if (location.pathname !== loginPath && !localStorage.getItem('userInfo')) {
    history.replace(loginPath)
    return {
      permission: JSON.parse(localStorage.getItem('access') || '') || [],
      currentUser: JSON.parse(localStorage.getItem('userInfo') || '') || {},
      settings: { ...defaultSettings, fixedHeader: true } as Partial<LayoutSettings>,
    };
  }
  return {
    permission: JSON.parse(localStorage.getItem('access') || '') || [],
    currentUser: JSON.parse(localStorage.getItem('userInfo') || '') || {},
@@ -31,10 +41,7 @@
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  return {
    siderWidth: '210',
    token: {
    },
    logo: false,
    avatarProps: {
      title: <AvatarName />,
      render: (_, avatarChildren) => {
@@ -43,14 +50,6 @@
    },
    waterMarkProps: {
      content: false,
    },
    onPageChange: () => {
      const { location: { pathname } } = history;
      // 如果没有登录,重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        // history.push(loginPath);
        return
      }
    },
    // 自定义 403 页面
    unAccessible: <div></div>,
@@ -76,7 +75,6 @@
      );
    },
    ...initialState?.settings,
    logo
  };
};
management/src/global.less
@@ -21,24 +21,6 @@
  left: unset;
}
.ant-pro-layout .ant-pro-sider.ant-pro-sider-fixed-mix {
  height: calc(100% - 74px);
  inset-block-start: 74px;
}
.ant-layout-has-sider>div:nth-child(1) {
  max-width: 210px !important;
  min-width: 64px !important;
}
.ant-layout-header {
  height: 74px !important;
}
.ant-pro-global-header {
  height: 74px !important;
}
canvas {
  display: block;
}
@@ -70,32 +52,6 @@
          display: block;
        }
      }
    }
  }
}
.del-confirm {
  .del-icon {
    margin-right: 5px;
    width: 22px;
    height: 22px;
    background-color: rgba(233, 157, 66, 1);
    color: #fff;
    border-radius: 50%;
    align-content: center;
    text-align: center;
  }
  .ant-modal-confirm-btns {
    .ant-btn-default:last-child {
      border-color: #1677ff !important;
      color: #fff !important;
      background-color: #1677ff !important;
    }
    .ant-btn-default {
      color: #000 !important;
      border-color: #d9d9d9 !important;
    }
  }
}
management/src/pages/Login/index.tsx
@@ -3,14 +3,12 @@
import { LockOutlined, SafetyOutlined, UserOutlined } from '@ant-design/icons';
import { LoginForm, ProFormText } from '@ant-design/pro-components';
import { useEmotionCss } from '@ant-design/use-emotion-css';
import { Helmet, history, SelectLang, useIntl, useModel } from '@umijs/max';
import { history, SelectLang, useIntl, useModel } from '@umijs/max';
import { Alert, message, Space } from 'antd';
// import CryptoJS from 'crypto-js';
import CryptoJS from 'crypto-js';
import React, { useRef, useState } from 'react';
import Captcha from 'react-captcha-code';
import { useAccess } from 'umi';
import Settings from '../../../config/defaultSettings';
import logo from '../../../public/logo/logo.png';
import EditPwd from './editPwd.jsx';
import { updatePwd } from './service.js';
import './style.less';
@@ -59,10 +57,7 @@
  const captchaRef = useRef();
  const [type, setType] = useState<string>('username');
  const { initialState, setInitialState } = useModel('@@initialState');
  const access = useAccess();
  const style1 = {
    display: 'flex',
  };
  const containerClassName = useEmotionCss(() => {
    return {
      height: '100vh',
@@ -77,16 +72,58 @@
      id: 'pages.login.success',
      defaultMessage: '登录成功!',
    });
    const userInfo = data.userInfo.user
    const userInfo = { userName: data.name };
    localStorage.setItem('userInfo', JSON.stringify(userInfo));
    let permissionList: any[] = [
      "/work_order_transaction_management/work_order_item_configuration",
      "/work_order_transaction_management",
      "/system_setting/role_management/edit",
      "/work_order_transaction_management/banner_management",
      "/work_order_transaction_management/banner_management/del",
      "/system_setting/position_management/add",
      "/message_notification/mark_read",
      "/system_setting/role_management",
      "/system_setting/unit_management/del",
      "/system_setting/people_management/freeze",
      "/work_order_transaction_management/problem_type_management",
      "/system_setting/position_management/edit",
      "/system_setting/people_management/del",
      "/work_order_transaction_management/problem_type_management/edit",
      "/position_management/del",
      "/system_setting/unit_management/edit",
      "/system_setting/people_management/edit",
      "/work_order_transaction_management/problem_type_management/add",
      "/system_setting/unit_management/add",
      "/system_setting/unit_management",
      "/message_notification",
      "/system_setting/role_management/add",
      "/work_order_transaction_management/banner_management/edit",
      "/system_setting/role_management/del",
      "/work_order_transaction_management/problem_type_management/del",
      "/system_setting/people_management/add",
      "/work_order_transaction_management/banner_management/add",
      "/system_setting/position_management",
      "/system_setting",
      "/system_setting/people_management",
    ];
    let accessObj: any = {};
    permissionList.map((item) => {
      if (JSON.stringify(data.menu) === JSON.stringify(['*:*:*'])) {
        accessObj[item] = true;
      } else {
        accessObj[item] = data.menu.includes(item);
      }
    });
    setInitialState((s: any) => ({
      ...s,
      token: 'data.token.access_token',
      token: data.token,
      permission: accessObj,
      currentUser: userInfo,
      settings: Settings,
    }));
    localStorage.setItem('access', JSON.stringify(accessObj));
    message.success(defaultLoginSuccessMessage);
    const urlParams = new URL(window.location.href).searchParams;
    setTimeout(() => {
@@ -94,48 +131,20 @@
    }, 0);
  };
  const filterPermission = (list: any[], arr: any[]) => {
    return list.map((item) => {
      if (item.children) {
        filterPermission(item.children, arr);
      }
      arr.push(item);
      return item;
    });
  };
  const handleClick = (e: String) => {
    setCaptcha(e);
  };
  // 生成随机字符串
  const generateRandomString = (length: number) => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const str = [];
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * chars.length);
      str.push(chars[randomIndex]);
    }
    return str.join('');
  };
  const handleSubmit = async (values: API.LoginParams) => {
    try {
      // 登录
      const res = await login({ ...values });
      if (res.code == 200) {
        let accessObj: any = {};
        localStorage.setItem('access', JSON.stringify(accessObj));
        setInitialState((s: any) => ({
          ...s,
          permission: accessObj,
        }));
        localStorage.setItem('token', res.token);
        getUserInfo(res);
        localStorage.setItem('token', res.data.token);
        getUserInfo(res.data);
        return;
      } else {
        throw new Error('登录发生错误');
      }
      // 如果失败去设置用户错误信息
      // setUserLoginState(res);
    } catch (error) {
      captchaRef?.current?.refresh();
    }
@@ -146,17 +155,6 @@
  return (
    <div className={containerClassName}>
      <div className="loginContent">
        <Helmet>
          <title>
            {intl.formatMessage({
              id: 'menu.login',
              defaultMessage: '登录页',
            })}
            - {Settings.title}
          </title>
        </Helmet>
        <Lang />
        <div
          style={{
            position: 'absolute',
@@ -164,36 +162,26 @@
            left: '50%',
            transform: 'translate(-50%,-50%)',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
          }}
        >
          {/* <div style={{ width: '787px' }}>
            <h1
              style={{ fontSize: '48px', color: '#fff', textAlign: 'center', marginBottom: '48px' }}
            >
              三个身边
          <div style={{ width: '787px', fontSize: '26px', textAlign: 'center' }}>
            <h1>
              “三个身边”群众工作机制问题化解
            </h1>
          </div> */}
            <h1>平台</h1>
          </div>
          <LoginForm
            contentStyle={{
              minWidth: 280,
              maxWidth: '75vw',
            }}
            logo={logo}
            title=""
            subTitle={' '}
            logo={false}
            title={false}
            subTitle={false}
            initialValues={{
              autoLogin: true,
            }}
            // actions={[
            //   <FormattedMessage
            //     key="loginWith"
            //     id="pages.login.loginWith"
            //     defaultMessage="其他登录方式"
            //   />,
            //   <ActionIcons key="icons" />,
            // ]}
            onFinish={async (values) => {
              if (values.code != captcha) {
                captchaRef?.current?.refresh();
@@ -201,31 +189,11 @@
                return;
              }
              delete values.code;
              values.password = CryptoJS.MD5(values.password).toString();
              await handleSubmit(values as API.LoginParams);
            }}
          >
            {/* <Tabs
            activeKey={type}
            onChange={setType}
            centered
            items={[
              {
                key: 'username',
                label: intl.formatMessage({
                  id: 'pages.login.accountLogin.tab',
                  defaultMessage: '账户密码登录',
                }),
              },
              {
                key: 'mobile',
                label: intl.formatMessage({
                  id: 'pages.login.phoneLogin.tab',
                  defaultMessage: '手机号登录',
                }),
              },
            ]}
          /> */}
            <h1 style={{ fontSize: '26px', textAlign: 'center', marginBottom: '20px' }}>登录</h1>
            {status === 'error' && loginType === 'username' && (
              <LoginMessage
                content={intl.formatMessage({
@@ -237,7 +205,7 @@
            {type === 'username' && (
              <>
                <ProFormText
                  name="username"
                  name="phone"
                  fieldProps={{
                    size: 'large',
                    prefix: <UserOutlined />,
@@ -283,68 +251,9 @@
                    <Captcha onChange={handleClick} ref={captchaRef} bgColor="#fff" />
                  </div>
                </Space>
                {/* <div
                  style={{ color: '#0086F6', textAlign: 'right', marginBottom: '21px' }}
                  className="login-form-forgot"
                  onClick={() => {
                    handleModalVisible(true);
                  }}
                >
                  修改密码
                </div> */}
              </>
            )}
            {status === 'error' && loginType === 'mobile' && <LoginMessage content="验证码错误" />}
            {/* <ProFormText
                fieldProps={{
                  size: 'large',
                  prefix: <MobileOutlined />,
                }}
                name="mobile"
                placeholder={intl.formatMessage({
                  id: 'pages.login.phoneNumber.placeholder',
                  defaultMessage: '手机号',
                })}
                rules={[
                  {
                    required: true,
                    message: (
                      <FormattedMessage
                        id="pages.login.phoneNumber.required"
                        defaultMessage="请输入手机号!"
                      />
                    ),
                  },
                  {
                    pattern: /^1\d{10}$/,
                    message: (
                      <FormattedMessage
                        id="pages.login.phoneNumber.invalid"
                        defaultMessage="手机号格式错误!"
                      />
                    ),
                  },
                ]}
              /> */}
            {/* <div
            style={{
              marginBottom: 24,
            }}
          >
            <ProFormCheckbox noStyle name="autoLogin">
              <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
            </ProFormCheckbox>
            <a
              style={{
                float: 'right',
              }}
            >
              <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
            </a>
          </div> */}
          </LoginForm>
        </div>
        <EditPwd
management/src/pages/Login/service.js
@@ -24,7 +24,7 @@
export async function login(data) {
  return request('/management/tUser/login', {
  return request('/api/huacheng-sangeshenbian/systemUser/login', {
    method: 'POST',
    data,
  });
management/src/pages/Login/style.less
@@ -1,7 +1,9 @@
.ant-pro-form-login-container{
.ant-pro-form-login-container {
    background-color: #fff;
    border-radius: 23px;
    padding: 45px 60px;
    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
    margin-left: 50px;
}
.ant-pro-form-login-header {
@@ -9,20 +11,6 @@
    height: 190px;
}
.ant-pro-form-login-top{
    width: 413px;
    height: 167px;
    margin-bottom: 64px;
    display: flex;
    justify-content: center;
}
.ant-pro-form-login-logo {
    width: 190px;
    height: 190px;
    overflow: hidden;
    margin-inline-end:0px
.ant-pro-form-login-top {
    display: none;
}
management/src/pages/message-notification/components/addAndEdit.jsx
@@ -86,7 +86,7 @@
  // 提交表单
  const submit = () => {
    form.validateFields().then(async (values) => {
      console.log('fileList',fileList)
      values.picUrl = fileList[0].url
      delete values.image
      if (searchParams.get('id')) {
management/src/pages/work-order/banner/components/addAndEdit.jsx
@@ -86,7 +86,7 @@
  // 提交表单
  const submit = () => {
    form.validateFields().then(async (values) => {
      console.log('fileList',fileList)
      values.picUrl = fileList[0].url
      delete values.image
      if (searchParams.get('id')) {
management/src/requestErrorConfig.ts
@@ -52,7 +52,7 @@
      const { data } = response as unknown as ResponseStructure;
      if (data?.code === 103 || data?.code === 401) {
        localStorage.clear()
        // history.replace('/login')
        history.replace('/login')
        return Promise.resolve(response)
      }
      if (data?.code != 200) {