/* * @Author: helin3 * @Date: 2024-03-27 15:16:08 * @LastEditors: zhanglin3 * @LastEditTime: 2024-09-09 17:38:42 * @Description: UAA相关接口模拟定义 * * 模拟接口文件路径遵循规范:`/mock/[模块名]/[功能名].mock.js` * 更详细的文档请参考:https://github.com/pengzhanbo/vite-plugin-mock-dev-server */ import { createReadStream, readFileSync } from 'node:fs'; import { Base64 } from 'js-base64'; import { defineMock, backend, normalResponse } from '@/../mock/shared/utils.js'; /** * 模拟生成访问令牌的函数 * @param {Object} body - 包含用户名和密码的对象 * @returns {Object} 返回一个包含访问令牌、刷新令牌等信息的对象,或在认证失败时返回错误信息。 */ const mockAccessToken = (body) => { let returnObj = {}; const { username, password } = body; const suffix = new Date().getTime(); // 根据当前时间戳生成模拟的Token和刷新Token const userInfo = { userId: 'admin', // 用户编号 userName: 'admin', // 用户名 userCode: 'admin', // 登录名 userAvatar: '', // 用户头像 userEmail: '', // 用户email userMobilephone: 'admin', // 联系电话 userSex: 'admin', // 性别 // 已授权的机构列表 authOrgs: [ { code: '500', // 机构编号 name: '宇信集团', // 机构名称 id: '500', instuCode: '', // 金融机构编号 instuName: '', // 金融机构名称 // 已授权角色列表 roles: [ { roleCode: '', // 角色编码 roleName: '', // 角色名称 }, ], // 当前选择机构 currOrg: { orgCode: '', // 机构编号 orgName: '', // 机构名称 instuCode: '', // 金融机构编号 instuName: '', // 金融机构名称 // 已授权角色列表 roles: [ { roleCode: '', // 角色编码 roleName: '', // 角色名称 }, ], }, }, { code: '5001', // 机构编号 name: '宇信科技', // 机构名称 id: '5001', instuCode: '', // 金融机构编号 instuName: '', // 金融机构名称 // 已授权角色列表 roles: [ { roleCode: '', // 角色编码 roleName: '', // 角色名称 }, ], // 当前选择机构 currOrg: { orgCode: '', // 机构编号 orgName: '', // 机构名称 instuCode: '', // 金融机构编号 instuName: '', // 金融机构名称 // 已授权角色列表 roles: [ { roleCode: '', // 角色编码 roleName: '', // 角色名称 }, ], }, }, ], org: { code: '500', // 机构编号 name: '宇信集团', // 机构名称 id: '500', }, roles: [{ id: '500', name: '宇信集团', code: 'YUSYS' }], additionals: { authOrgRoles: [ { orgCde: '500', orgName: '宇信集团', lastUseTime: '2024-07-25 17:55:35', usrRoleRelId: '6ACEAA02D8DC11EDBFAC005056BD1C9B', roleId: '7E6B6DD5DABF498C966D483605691E15', roleName: '决策引擎超级管理员', orgId: '500', roleCde: 'shuffle_admin', }, { orgCde: '500', orgName: '宇信集团', lastUseTime: '2024-07-30 16:14:03', usrRoleRelId: 'a2fa6f4c28e34de2ab22cf549de41e31', roleId: 'cc81a8d86f274c81bc680a0bbd27e358', roleName: '系统管理员角色', orgId: '500', roleCde: 'R001', }, ], currentOrgRole: { orgCde: '500', orgName: '宇信集团', lastUseTime: '2024-07-30 16:14:03', usrRoleRelId: 'a2fa6f4c28e34de2ab22cf549de41e31', roleId: 'cc81a8d86f274c81bc680a0bbd27e358', roleName: '系统管理员角色', orgId: '500', roleCde: 'R001', }, }, }; const tempReturnObj = { accessToken: `MOCK-ACCESSTOKEN-${suffix}`, expiresIn: 3600, // 令牌有效期为3600秒 refreshToken: `MOCK-REFRESHTOKEN-${suffix}`, // 用户信息,经过Base64加密过后的登录成功的用户信息 userInfo: Base64.encode(JSON.stringify(userInfo)), }; // grantType-授权类型: password-登录 subject-切换主体 const { grantType, orgCode } = body; // 根据不同的grantType返回不同的模拟响应 if (grantType === 'password') { // 验证用户名和密码,根据结果返回不同的对象 if (username !== 'admin') { // 账号或密码错误时返回的错误信息 returnObj = normalResponse('', 'UAASYS005', '当前用户不存在或登录密码错误'); } else { const flag = Math.random() < 0.7 ? 1 : 0; if (flag) { // 验证成功时返回模拟的Token信息 returnObj = Object.assign(normalResponse(), { data: tempReturnObj }); } else { // 随机生成错误场景 const codes = [ { code: 'UAASYS001', message: '验证码错误' }, { code: 'UAASYS002', message: '需进行验证码验证' }, { code: 'UAASYS003', message: '首次登录,需进行密码修改', data: { accessToken: `MOCK-ACCESSTOKEN-${suffix}`, expiresIn: 3600, // 令牌有效期为3600秒 refreshToken: `MOCK-REFRESHTOKEN-${suffix}`, }, }, { code: 'UAASYS004', message: '当前用户的状态不正确' }, // { code: 'UAASYS005', message: '当前用户不存在或登录密码错误' }, { code: 'UAASYS006', message: '当前系统处理异常' }, { code: 'UAASYS007', message: '当前客户端认证信息不存在' }, // { code: 'UAASYS008', message: '当前授权模式不存在' }, { code: 'UAASYS009', message: '当前客户端认证信息异常' }, { code: 'UAASYS010', message: '当前用户需要进行密码修改', data: { accessToken: `MOCK-ACCESSTOKEN-${suffix}`, expiresIn: 3600, // 令牌有效期为3600秒 refreshToken: `MOCK-REFRESHTOKEN-${suffix}`, }, }, { code: 'UAASYS011', message: '当前时间不允许登录' }, { code: 'UAASYS012', message: '用户登录密码有效期已过' }, { code: 'UAASYS013', message: '用户达到系统登录人数上限' }, ]; const index = Math.floor(Math.random() * codes.length); returnObj = normalResponse(codes[index].data || '', codes[index].code, codes[index].message); } } } else if (grantType === 'subject') { const org = userInfo.authOrgs.filter((item) => { return item.code === orgCode; }); tempReturnObj.org = { id: org.id, code: org.code, name: org.name, }; returnObj = Object.assign(normalResponse(), { data: tempReturnObj }); } else if (grantType === 'refresh') { returnObj = Object.assign(normalResponse(), { data: tempReturnObj }); } else { // 对于不支持的grantType返回错误响应 returnObj = normalResponse('', 'UAASYS008', '当前授权模式不存在'); } return returnObj; }; /** * 模拟生成是否展示验证码及验证码base64 * * @returns {Object} 返回展示验证码标识及验证码base64 */ const mockImageCode = () => { // 随机模拟是否开启验证码验证机制 const flag = Math.random() < 0.6 ? 1 : 0; const tempReturnObj = { imageShowInd: flag, }; // 模拟获取图片验证码的响应:验证码展示标识为是时,此处为Base64加密后的图片验证码的byte数组信息 if (flag) { tempReturnObj.imageCode = readFileSync('./mock/oca/data/image-captcha.png').toString('base64'); } return normalResponse(tempReturnObj); }; /** * 定义模拟API集合,用于开发和测试过程中对真实API的模拟。 * @param {Array} mocks - API模拟的配置数组。 * @returns {Object} 返回一个根据传入的mocks配置的模拟API对象。 */ export default defineMock([ { url: `${backend.uaaService}/oauth/hasImageCode`, // 查询配置是否需要进行验证码 method: 'POST', enabled: true, // 启用该接口的模拟 body: () => { // 模拟注销操作的响应,实际上该接口不返回任何信息 return normalResponse('', undefined, '注-真实注销接口没有返回报文信息'); }, }, // { // url: `${backend.uaaService}/oauth/token`, // OAuth认证服务的token获取接口 // method: 'POST', // enabled: true, // 启用该接口的模拟 // body: ({ body }) => { // let response = {}; // const { grantType } = body; // // 根据不同的grantType返回不同的模拟响应 // if (grantType === 'password') { // response = mockAccessToken(body); // 模拟使用密码或oca令牌类型的访问令牌获取 // } else if (grantType === 'refresh') { // response = mockRefreshToken(body); // 模拟使用刷新令牌获取新的访问令牌 // } else { // // 对于不支持的grantType返回错误响应 // response = normalResponse('', '-1', '/oauth/token mock error.'); // } // return response; // }, // }, { url: `${backend.uaaService}/api/logout`, // 用户注销接口 method: 'POST', enabled: true, // 启用该接口的模拟 body: () => { // 模拟注销操作的响应,实际上该接口不返回任何信息 return normalResponse('', undefined, '注-真实注销接口没有返回报文信息'); }, }, { url: `${backend.uaaService}/api/codeimage/:uuid`, method: ['GET', 'POST'], type: 'xxx.png', // 通过传入名称来设置返回的文件类型 enabled: true, body: () => { // 模拟获取图片验证码的响应 // 返回一个指向根目录下mock/oca/data/image-captcha.png文件的可读流 return createReadStream('./mock/oca/data/image-captcha.png'); }, }, // 首次验证码获取 { url: `${backend.uaaService}/api/verification/code/generate`, method: ['POST'], enabled: true, body: () => { return mockImageCode(); }, }, // 验证码重新获取 { url: `${backend.uaaService}/api/verification/code/regenerate`, method: ['POST'], enabled: true, body: () => { return mockImageCode(); }, }, // 登录/登录后主体切换/刷新token { url: `${backend.uaaService}/oauth/token`, // OAuth认证服务的token获取接口 method: 'POST', enabled: true, // 启用该接口的模拟 // delay: 2000, // 设置延迟时间为1000毫秒(即1秒) body: ({ body }) => { return mockAccessToken(body); }, }, ]);