Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
186 lines
5.5 KiB
TypeScript
186 lines
5.5 KiB
TypeScript
/**
|
||
* 生成微信服务号Token和EncodingAESKey
|
||
*
|
||
* 功能:
|
||
* 1. 生成符合要求的Token(3-32位)
|
||
* 2. 生成符合要求的EncodingAESKey(43位)
|
||
* 3. 输出可直接复制的环境变量配置
|
||
*/
|
||
|
||
import crypto from 'crypto';
|
||
|
||
console.log('🔐 微信服务号Token和EncodingAESKey生成器');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
// ==================== 1. 生成Token ====================
|
||
|
||
console.log('🔑 生成Token(用于签名验证)...\n');
|
||
|
||
function generateToken(length: number = 32): string {
|
||
// 生成随机字符串(只包含字母和数字)
|
||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||
let token = '';
|
||
const randomBytes = crypto.randomBytes(length);
|
||
|
||
for (let i = 0; i < length; i++) {
|
||
token += chars[randomBytes[i] % chars.length];
|
||
}
|
||
|
||
return token;
|
||
}
|
||
|
||
const token = generateToken(32);
|
||
|
||
console.log(' 生成的Token:');
|
||
console.log(` ${token}`);
|
||
console.log(` 长度: ${token.length}位`);
|
||
console.log(` 说明: 用于URL验证和消息签名验证`);
|
||
console.log('');
|
||
|
||
// ==================== 2. 生成EncodingAESKey ====================
|
||
|
||
console.log('🔐 生成EncodingAESKey(用于消息加解密)...\n');
|
||
|
||
function generateEncodingAESKey(): string {
|
||
// 生成43位随机字符串(Base64字符集,不包含/+=)
|
||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||
let aesKey = '';
|
||
const randomBytes = crypto.randomBytes(43);
|
||
|
||
for (let i = 0; i < 43; i++) {
|
||
aesKey += chars[randomBytes[i] % chars.length];
|
||
}
|
||
|
||
return aesKey;
|
||
}
|
||
|
||
const aesKey = generateEncodingAESKey();
|
||
|
||
console.log(' 生成的EncodingAESKey:');
|
||
console.log(` ${aesKey}`);
|
||
console.log(` 长度: ${aesKey.length}位`);
|
||
console.log(` 说明: 用于消息加密和解密(安全模式必需)`);
|
||
console.log('');
|
||
|
||
// ==================== 3. 输出环境变量配置 ====================
|
||
|
||
console.log('='.repeat(60));
|
||
console.log('\n📋 环境变量配置(复制以下内容到 backend/.env 文件)\n');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
console.log('# ==========================================');
|
||
console.log('# 微信服务号配置(患者端)');
|
||
console.log('# ==========================================');
|
||
console.log('');
|
||
console.log('# 微信服务号基础配置');
|
||
console.log('WECHAT_MP_APP_ID=wx062568ff49e4570c');
|
||
console.log('WECHAT_MP_APP_SECRET=c0d19435d1a1e948939c16d767ec0faf');
|
||
console.log('');
|
||
console.log('# 微信服务号回调配置(消息加解密,安全模式)');
|
||
console.log(`WECHAT_MP_TOKEN=${token}`);
|
||
console.log(`WECHAT_MP_ENCODING_AES_KEY=${aesKey}`);
|
||
console.log('');
|
||
console.log('# 微信小程序配置(可选,后续开发)');
|
||
console.log('WECHAT_MINI_APP_ID=');
|
||
console.log('');
|
||
|
||
// ==================== 4. 输出微信公众平台配置 ====================
|
||
|
||
console.log('='.repeat(60));
|
||
console.log('\n📋 微信公众平台配置(复制以下内容到公众平台)\n');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
console.log('登录地址:https://mp.weixin.qq.com/');
|
||
console.log('配置路径:设置与开发 → 基本配置 → 服务器配置');
|
||
console.log('');
|
||
console.log('配置参数:');
|
||
console.log('');
|
||
console.log(' 【URL】');
|
||
console.log(' 生产环境:https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback');
|
||
console.log(' 开发环境:https://devlocal.xunzhengyixue.com/api/v1/iit/patient-wechat/callback');
|
||
console.log('');
|
||
console.log(' 【Token】');
|
||
console.log(` ${token}`);
|
||
console.log('');
|
||
console.log(' 【EncodingAESKey】');
|
||
console.log(` ${aesKey}`);
|
||
console.log('');
|
||
console.log(' 【消息加解密方式】');
|
||
console.log(' 安全模式(推荐)');
|
||
console.log('');
|
||
console.log(' 【数据格式】');
|
||
console.log(' XML');
|
||
console.log('');
|
||
|
||
// ==================== 5. 输出后续步骤 ====================
|
||
|
||
console.log('='.repeat(60));
|
||
console.log('\n📝 后续步骤\n');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
console.log('Step 1: 更新环境变量');
|
||
console.log(' 1. 复制上面的环境变量配置');
|
||
console.log(' 2. 粘贴到 backend/.env 文件');
|
||
console.log(' 3. 保存文件');
|
||
console.log('');
|
||
|
||
console.log('Step 2: 验证配置');
|
||
console.log(' 运行配置检查脚本:');
|
||
console.log(' npx tsx src/modules/iit-manager/test-patient-wechat-config.ts');
|
||
console.log('');
|
||
|
||
console.log('Step 3: 启动服务');
|
||
console.log(' 本地开发:npm run dev');
|
||
console.log(' 生产环境:部署到SAE');
|
||
console.log('');
|
||
|
||
console.log('Step 4: 配置微信公众平台');
|
||
console.log(' 1. 登录微信公众平台');
|
||
console.log(' 2. 填写上面的配置参数');
|
||
console.log(' 3. 点击"提交"进行URL验证');
|
||
console.log(' 4. 验证成功后点击"启用"');
|
||
console.log('');
|
||
|
||
console.log('Step 5: 测试功能');
|
||
console.log(' 运行URL验证测试脚本:');
|
||
console.log(' npx tsx src/modules/iit-manager/test-patient-wechat-url-verify.ts');
|
||
console.log('');
|
||
|
||
console.log('='.repeat(60));
|
||
console.log('\n⚠️ 重要提示\n');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
console.log(' 1. Token和EncodingAESKey必须在.env和微信公众平台中保持一致');
|
||
console.log(' 2. 不要将Token和EncodingAESKey提交到Git仓库');
|
||
console.log(' 3. 生产环境需要在SAE中配置这些环境变量');
|
||
console.log(' 4. 如果配置错误,可以重新运行本脚本生成新的值');
|
||
console.log(' 5. 修改配置后需要重启服务才能生效');
|
||
console.log('');
|
||
|
||
console.log('🎉 生成完成!');
|
||
console.log('');
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|