菜单与 审核按钮,登录新用户修改密码

This commit is contained in:
孙景学
2025-08-05 11:24:32 +08:00
parent d73f2ee647
commit 26722d643d
17 changed files with 260 additions and 91 deletions

View File

@ -1,10 +1,8 @@
import React, { useEffect, useState } from 'react';
import { Card, Row, Col, Spin, message } from 'antd';
import { Column, Pie, Bar } from '@ant-design/charts';
import ChangePasswordModal from './components/ChangePasswordModal';
import {
changePasswordOnFirstLogin,
getYearcountNum,
getAccessTypeCountNum,
getSupplierTypeCountNum,
@ -22,38 +20,6 @@ const HomeDashboard: React.FC = () => {
const [supplierAuditData, setSupplierAuditData] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
// ======= 新增部分:弹窗控制 =======
const [showChangePwd, setShowChangePwd] = useState(false);
useEffect(() => {
// 检查 firstLogin
const userStr = sessionStorage.getItem('currentUser');
if (userStr) {
try {
const userObj = JSON.parse(userStr);
if (userObj?.supplierUser?.firstLogin === 0) {
setShowChangePwd(true);
}
} catch (e) { }
}
}, []);
// 修改密码确认回调
const handleChangePwd = async (values: { userId: string; newPassword: string; confirmPassword: string; }) => {
try {
await changePasswordOnFirstLogin({ ...values });
message.success('密码修改成功,请重新登录');
// 更新缓存 firstLogin=1
const userStr = sessionStorage.getItem('currentUser');
if (userStr) {
const userObj = JSON.parse(userStr);
if (userObj?.supplierUser) userObj.supplierUser.firstLogin = 1;
sessionStorage.setItem('currentUser', JSON.stringify(userObj));
}
setShowChangePwd(false);
} catch (e: any) {
message.error(e?.message || '修改密码失败');
}
};
useEffect(() => {
setLoading(true);
@ -193,19 +159,6 @@ const HomeDashboard: React.FC = () => {
return (
<>
<ChangePasswordModal
visible={showChangePwd}
onOk={handleChangePwd}
onCancel={() => {
setShowChangePwd(false)
const userStr = sessionStorage.getItem('currentUser');
if (userStr) {
const userObj = JSON.parse(userStr);
if (userObj?.supplierUser) userObj.supplierUser.firstLogin = 1;
sessionStorage.setItem('currentUser', JSON.stringify(userObj));
}
}}
/>
<Spin spinning={loading}>
<Row gutter={[24, 24]}>
{/* 第一行3图 */}

View File

@ -1,18 +1,5 @@
import request from '@/utils/request';
/**
*
* @param params
* @returns
*
*/
interface PasswordOnFirstLogin {
userId:string;
newPassword:string;
confirmPassword:string;
}
export const changePasswordOnFirstLogin = (data:PasswordOnFirstLogin) => request.post(`/v1/login/supplier/changePasswordOnFirstLogin`, { data});
/**
*
* @param params

View File

@ -0,0 +1,72 @@
import React, { useEffect } from 'react';
import { Modal, Form, Input, Button } from 'antd';
// props: visible, onOk, onCancel
const ChangePasswordModal: React.FC<{
visible: boolean;
onOk: (values: { userId: string; newPassword: string; confirmPassword: string }) => Promise<void>;
}> = ({ visible, onOk }) => {
const [form] = Form.useForm();
const handleOk = async () => {
try {
const values = await form.validateFields();
await onOk({ ...values });
form.resetFields();
} catch (err) {}
};
return (
<Modal
title="首次登录请修改密码"
visible={visible}
onOk={handleOk}
okText="确认修改"
maskClosable={false}
closable={false}
destroyOnClose
footer={null}
>
<Form
form={form}
labelCol={{ flex: '100px' }}
initialValues={{ newPassword: '', confirmPassword: '' }}
>
<Form.Item name="userId" noStyle>
<Input type="hidden" />
</Form.Item>
<Form.Item
label="新密码"
name="newPassword"
rules={[
{ required: true, message: '请输入新密码' },
]}
>
<Input.Password />
</Form.Item>
<Form.Item
label="确认新密码"
name="confirmPassword"
dependencies={['newPassword']}
rules={[
{ required: true, message: '请确认新密码' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('newPassword') === value) return Promise.resolve();
return Promise.reject('两次输入密码不一致');
},
}),
]}
>
<Input.Password />
</Form.Item>
</Form>
<div style={{ textAlign: 'right' }}>
<Button type="primary" onClick={handleOk}>
</Button>
</div>
</Modal>
);
};
export default ChangePasswordModal;

View File

@ -3,7 +3,8 @@ import { Form, Input, Button, Checkbox, Tabs, message } from 'antd';
import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import { history, useIntl } from 'umi';
import './login.less';
import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo, refreshDictCache, findMenuList } from '@/servers/api/login';
import { getCaptcha, supplierLogin, expertLogin, accountLogin, getUserinfo, refreshDictCache, findMenuList, changePasswordOnFirstLogin } from '@/servers/api/login';
import ChangePasswordModal from './components/ChangePasswordModal';
import { encryptWithRsa } from '@/utils/encryptWithRsa'
@ -14,6 +15,10 @@ const LoginPage: React.FC = () => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [captchaImg, setCaptchaImg] = useState<string>('');
const [userId, setUserId] = useState<string>('');
// ======= 修改密码弹窗控制 =======
const [showChangePwd, setShowChangePwd] = useState(false);
// const [captchaKey, setCaptchaKey] = useState<string>('');
//切换后 走不同接口
const loginApiMap: { [key: string]: (params: any) => Promise<any> } = {
@ -51,6 +56,26 @@ const LoginPage: React.FC = () => {
// });
// }
}, [form]);
// 修改密码确认回调
const handleChangePwd = async (values: { userId: string; newPassword: string; confirmPassword: string; }) => {
try {
await changePasswordOnFirstLogin({
userId: userId,
newPassword: encryptWithRsa(values.newPassword, false),
confirmPassword: encryptWithRsa(values.confirmPassword, false)
}).then((res) => {
if(res.data) {
setShowChangePwd(false);
message.success('修改成功,请重新登录');
} else {
message.success('修改密码失败');
}
})
} catch (e: any) {
message.error(e?.message || '修改密码失败');
}
};
const onFinish = async (values: any) => {
setLoading(true);
try {
@ -92,11 +117,19 @@ const LoginPage: React.FC = () => {
sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data));
await getUserinfo().then(async (res) => {
const roleIdList = res.authorityList.map((item: any) => item.roleId);
console.log(res);
setUserId(res.userId)
sessionStorage.setItem('Userinfo', JSON.stringify(res));
const menuList: any = await findMenuList({ roleIdList });
sessionStorage.setItem('menuList', JSON.stringify(menuList.data));
message.success('登录成功');
history.push('/index');
//新用户需要修改一次密码
if (loginRes.data?.supplierUser?.firstLogin === 1) {
setShowChangePwd(true);
} else {
message.success('登录成功');
history.push('/index');
}
});
} else {
message.error(loginRes.message || '登录失败');
@ -157,6 +190,12 @@ const LoginPage: React.FC = () => {
}
return (
<>
<ChangePasswordModal
visible={showChangePwd}
onOk={handleChangePwd}
/>
<div className='login-page'>
<div className='login-container'>
{/* <div className='back-home'>
@ -245,6 +284,7 @@ const LoginPage: React.FC = () => {
</Form>
</div>
</div>
</>
);
};

View File

@ -10,7 +10,7 @@ import CategorySelector from '@/components/CategorySelector';
import AdmissionTypeSelect from '@/components/CommonSelect/AdmissionTypeSelect';
import AccessDepartmentSelect from "@/components/AccessDepartmentSelect"
//接口
import { getPage, startApprove } from './services'
import { getPage, startApprove, supplierChangeApprove } from './services'
import { getDictList } from '@/servers/api/dicts'
//统一列表分页
import tableProps from '@/utils/tableProps'
@ -120,6 +120,15 @@ const SupplierCategoryEntry: React.FC = () => {
</a>
)}
{record.approveStatus === '0' && (
<Button type="link" onClick={() => {
supplierChangeApprove({ id: record.id, approveStatus: '1' }).then(() => {
handleReset()
})
}}>
</Button>
)}
</Space>
),
},
@ -131,7 +140,7 @@ const SupplierCategoryEntry: React.FC = () => {
<div className="filter-action-row">
<Form layout="inline" form={form} className="filter-form" onFinish={getList}>
<Form.Item name="accessType" label="准入方式">
<AdmissionTypeSelect/>
<AdmissionTypeSelect />
</Form.Item>
<Form.Item name="orgId" label="准入单位">
<AccessDepartmentSelect placeholder={'请选择准入单位'} />

View File

@ -62,3 +62,6 @@ export const add = (data: addInterface) => request.post('/coscoAccessWorkCategor
* 品类选择查询树
*/
export const categoryTree = () => request.get('/cosco/category/categoryTree');
export const supplierChangeApprove = (data: { id:string; approveStatus:string }) => request.post('/synchronous/receiveCategoryApprove', { data });

View File

@ -13,7 +13,7 @@ import AdmissionTypeSelect from '@/components/CommonSelect/AdmissionTypeSelect';
import AccessStatusSelect from '@/components/CommonSelect/AccessStatusSelect';
import AccessDepartmentSelect from "@/components/AccessDepartmentSelect"
//接口
import { getPage, startApprove } from './services'
import { getPage, startApprove, supplierChangeApprove } from './services'
//统一列表分页
import tableProps from '@/utils/tableProps'
@ -112,7 +112,7 @@ const AccessManagement: React.FC = () => {
},
{
title: '操作',
width: 200,
width: 220,
fixed: 'right',
render: (_: any, record: any) => (
<Space>
@ -127,6 +127,15 @@ const AccessManagement: React.FC = () => {
<a onClick={() => openModal('result', record)}></a>
</>
)}
{record.approveStatus === '0' && (
<Button type="link" onClick={() => {
supplierChangeApprove({ id: record.id, approveStatus: '1' }).then(() => {
handleReset()
})
}}>
</Button>
)}
</Space>
),
@ -173,7 +182,7 @@ const AccessManagement: React.FC = () => {
dataSource={data}
columns={columns}
loading={loading}
pagination={{...tableProps.pagination, total: pagination.total }}
pagination={{ ...tableProps.pagination, total: pagination.total }}
onChange={(pagination) => {
const values = form.getFieldsValue();
getList(values, pagination.current!, pagination.pageSize!)

View File

@ -123,4 +123,4 @@ export const startApprove = (params: startApproveData) => request.get(`/coscoAcc
*/
export const reviewInfoData = (params: startApproveData) => request.get(`/coscoAccessWork/reviewInfoData`, { params });
export const supplierChangeApprove = (data: { id:string; approveStatus:string }) => request.post('/synchronous/receiveApprove', { data });

View File

@ -5,7 +5,7 @@ import { SearchOutlined, DeleteOutlined } from '@ant-design/icons';
import DetailView from './components/DetailView';
import RegionTypeSelect from '@/components/CommonSelect/RegionTypeSelect'
//接口
import { getPage } from './services';
import { getPage, supplierChangeApprove } from './services';
import type { ColumnsType } from 'antd/es/table';
//字典
import { getDictList } from '@/servers/api/dicts'
@ -189,9 +189,22 @@ const SupplierChangeReviewManage: React.FC<Props> = ({ dispatch }) => {
width: 160,
fixed: 'right',
render: (_: any, record: any) => (
<Button type="link" onClick={() => handleDetail(record)}>
</Button>
<>
<Button type="link" onClick={() => handleDetail(record)}>
</Button>
{/* 测试使用,需删除 */}
{ record.approveStatus === '0' && (
<Button type="link" onClick={() => {
supplierChangeApprove({ id:record.id, approveStatus: '1' }).then(() => {
handleReset()
})
}}>
</Button>
)}
</>
),
},
];

View File

@ -21,4 +21,4 @@ export const supplierChangeApplyById = (id: string) => request.get(`/coscoSuppli
export const supplierChangeApprove = (data: { id:string; approveStatus:string }) => request.post('/synchronous/supplierChangeApprove', { data });

View File

@ -8,7 +8,7 @@ import ViewBlacklistModal from './components/ViewBlacklistModal';
import AccessDepartmentSelect from "@/components/AccessDepartmentSelect"
//接口
import { getDictList } from '@/servers/api/dicts'
import { getPage } from './services'
import { getPage, supplierChangeApprove } from './services'
//统一列表分页
import tableProps from '@/utils/tableProps'
import moment from 'moment';
@ -102,10 +102,11 @@ const supplierExitAudit: React.FC = () => {
title: "操作",
key: "option",
align: "center",
width: 100,
width: 140,
fixed: 'right',
render: (record: any) => (
<a
<>
<a
onClick={() => {
setSelectedRecordId(record.id);
setViewVisible(true);
@ -113,6 +114,17 @@ const supplierExitAudit: React.FC = () => {
>
</a>
{record.approveStatus === '0' && (
<Button type="link" onClick={() => {
supplierChangeApprove({ id: record.id, approveStatus: '1' }).then(() => {
handleReset()
})
}}>
</Button>
)}
</>
),
},
];

View File

@ -84,4 +84,4 @@ export const coscoSupplierexit = (id: string) => request.get(`/coscoSupplierexit
export const supplierChangeApprove = (data: { id:string; approveStatus:string }) => request.post('/synchronous/supplierCategoryTcApprove', { data });