feat(admin): Add user management and upgrade to module permission system
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
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
# REDCap Docker 本地部署问题解决记录
|
||||
|
||||
**<EFBFBD>交<EFBFBD>嚗?* 2026-01-02
|
||||
**<EFBFBD><EFBFBD>𧋦嚗?* REDCap 15.8.0
|
||||
**<EFBFBD>臬<EFBFBD>嚗?* Windows 10 + Docker Desktop + Docker Compose
|
||||
**日期:** 2026-01-02
|
||||
**版本:** REDCap 15.8.0
|
||||
**环境:** Windows 10 + Docker Desktop + Docker Compose
|
||||
|
||||
---
|
||||
|
||||
## 📋 部署成功确认
|
||||
|
||||
<EFBFBD>?**REDCap 15.8.0 撌脫<EFBFBD><EFBFBD>罸<EFBFBD>蝵脣銁<EFBFBD>砍𧑐Docker<EFBFBD>臬<EFBFBD>**
|
||||
✅ **REDCap 15.8.0 已成功部署在本地Docker环境**
|
||||
|
||||
- **霈輸䔮<EFBFBD>啣<EFBFBD>嚗?* http://localhost:8080/
|
||||
- **访问地址:** http://localhost:8080/
|
||||
- **管理员账户:** Admin / Admin123!
|
||||
- **<EFBFBD>唳旿摨橒<EFBFBD>** MySQL 8.0嚗㇄ocker摰孵膥嚗?
|
||||
- **PHPMyAdmin嚗?* http://localhost:8081/
|
||||
- **数据库:** MySQL 8.0(Docker容器)
|
||||
- **PHPMyAdmin:** http://localhost:8081/
|
||||
|
||||
---
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
|
||||
### 问题1:ERR_CONTENT_DECODING_FAILED
|
||||
|
||||
**<EFBFBD>啗情嚗?*
|
||||
**现象:**
|
||||
- 浏览器访问REDCap首页时报错:`net::ERR_CONTENT_DECODING_FAILED 200 (OK)`
|
||||
- CSS/JS资源加载失败
|
||||
|
||||
**<EFBFBD>寞𧋦<EFBFBD>笔<EFBFBD>嚗?*
|
||||
**根本原因:**
|
||||
1. Apache的`mod_deflate`模块与PHP的`zlib.output_compression`冲突
|
||||
2. REDCap皞鞟<EFBFBD>銝剖𢆡<EFBFBD><EFBFBD>鍳<EFBFBD>其<EFBFBD><EFBFBD>讠憬嚗ǑSystem.php`<EFBFBD><EFBFBD>general_settings.php`銝剔<EFBFBD>`ini_set`嚗?
|
||||
3. 撖潸稲<EFBFBD>唳旿鋡怠<EFBFBD>甈∪<EFBFBD>蝻抬<EFBFBD>瘚讛<EFBFBD><EFBFBD>冽<EFBFBD>瘜閗圾<EFBFBD>?
|
||||
2. REDCap源码中动态启用了压缩(`System.php`、`general_settings.php`中的`ini_set`)
|
||||
3. 导致数据被多次压缩,浏览器无法解码
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>嚗?*
|
||||
1. <EFBFBD>?<3F>灼docker-entrypoint.sh`銝剖撩<E58996>嗥<EFBFBD><E597A5>杗pache<EFBFBD><EFBFBD>eflate璅∪<EFBFBD>嚗䫤a2dismod -f deflate`
|
||||
2. <EFBFBD>?<3F>灼php.ini`銝剜遬撘誩<EFBFBD><EFBFBD>剖<EFBFBD>蝻抬<EFBFBD>
|
||||
**解决方案:**
|
||||
1. ✅ 在`docker-entrypoint.sh`中强制禁用Apache的deflate模块:`a2dismod -f deflate`
|
||||
2. ✅ 在`php.ini`中显式关闭压缩:
|
||||
```ini
|
||||
zlib.output_compression = Off
|
||||
output_buffering = Off
|
||||
```
|
||||
3. <EFBFBD>?<3F>灼docker-entrypoint.sh`銝剛䌊<EFBFBD>冽釣<EFBFBD>䟕EDCap皞鞟<EFBFBD>銝剔<EFBFBD>`ini_set('zlib.output_compression', ...)`
|
||||
3. ✅ 在`docker-entrypoint.sh`中自动注释REDCap源码中的`ini_set('zlib.output_compression', ...)`
|
||||
|
||||
**憸<EFBFBD>俈<EFBFBD>芣鴌嚗?*
|
||||
**预防措施:**
|
||||
- 已在`redcap.conf`中注释掉`mod_deflate`配置
|
||||
- 开发环境不需要Gzip压缩,可提高调试效率
|
||||
|
||||
@@ -47,54 +47,54 @@
|
||||
|
||||
### 问题2:Base URL配置错误
|
||||
|
||||
**<EFBFBD>啗情嚗?*
|
||||
**现象:**
|
||||
- CSS/JS文件路径包含多余的`/redcap/`前缀
|
||||
- 例如:`http://localhost:8080/redcap/redcap_v15.8.0/Resources/...`
|
||||
- 导致404错误
|
||||
|
||||
**<EFBFBD>寞𧋦<EFBFBD>笔<EFBFBD>嚗?*
|
||||
**根本原因:**
|
||||
- REDCap数据库配置表`redcap_config`中的`redcap_base_url`设置为`http://localhost:8080/redcap`
|
||||
- 但Apache的`DocumentRoot`实际指向`/var/www/html/redcap_v15.8.0`
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>嚗?*
|
||||
**解决方案:**
|
||||
```sql
|
||||
UPDATE redcap_config
|
||||
SET value = 'http://localhost:8080'
|
||||
WHERE field_name = 'redcap_base_url';
|
||||
```
|
||||
|
||||
**憸<EFBFBD>俈<EFBFBD>芣鴌嚗?*
|
||||
- <20>典<EFBFBD>鋆<EFBFBD><E98B86>撖潭<E69296>SQL撖澆<E69296><E6BE86>嗥&靽𨈚ase URL銝𥟠ocumentRoot銝<EFBFBD><EFBFBD>?
|
||||
**预防措施:**
|
||||
- 在安装向导或SQL导入时确保Base URL与DocumentRoot一致
|
||||
|
||||
---
|
||||
|
||||
### <EFBFBD>桅<EFBFBD>3嚗𡁶蒈敶訫仃韐?- <20>滚<EFBFBD><E6BB9A>唳旿<E594B3>䭾<EFBFBD><E4ADBE>㰘蝸
|
||||
### 问题3:登录失败 - 响应数据无法加载
|
||||
|
||||
**<EFBFBD>啗情嚗?*
|
||||
- 颲枏<E9A2B2>甇<EFBFBD>&<EFBFBD><EFBC86>鍂<EFBFBD>瑕<EFBFBD>撖<EFBFBD><E69296><EFBFBD>𠬍<EFBFBD>憿菟𢒰銝滩歲頧?
|
||||
**现象:**
|
||||
- 输入正确的用户名密码后,页面不跳转
|
||||
- Network面板显示POST请求返回200,但"无法加载响应数据"
|
||||
|
||||
**<EFBFBD>寞𧋦<EFBFBD>笔<EFBFBD>嚗?*
|
||||
- **`database.php`<EFBFBD><EFBFBD>辣<EFBFBD>怠偏<EFBFBD>头?>`PHP蝏𤘪<EFBFBD><EFBFBD><EFBFBD>倌<EFBFBD>𣬚征銵?*
|
||||
**根本原因:**
|
||||
- **`database.php`文件末尾有`?>`PHP结束标签和空行**
|
||||
- Windows系统的CRLF换行符被输出到HTTP响应
|
||||
- 撖潸稲<E6BDB8>滚<EFBFBD>雿𤘪情<F0A498AA>橒<EFBFBD>瘚讛<E7989A><E8AE9B>冽<EFBFBD>瘜閗圾<E99697>?
|
||||
- 导致响应体污染,浏览器无法解析
|
||||
|
||||
**霂衣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?*
|
||||
**详细分析:**
|
||||
```bash
|
||||
# database.php<EFBFBD>怠偏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>剛<EFBFBD><EFBFBD>嗅<EFBFBD>摰?
|
||||
# database.php末尾的十六进制内容
|
||||
00000050: e585 a80d 0a20 2a2f 0d0a 0d0a 3f3e 0d0a ..... */....?>..
|
||||
00000060: 0d0a 0d0a ....
|
||||
# `*/` CRLF CRLF `?>` CRLF CRLF CRLF
|
||||
```
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>嚗?*
|
||||
1. <20>?**<2A>𣳇膄`database.php`<EFBFBD>怠偏<EFBFBD><EFBFBD>?>`<60>峕<EFBFBD><E5B395>厩征銵?*
|
||||
2. <20>?**<2A>𥕦遣`.gitattributes`撘箏<EFBFBD>PHP<EFBFBD><EFBFBD>辣雿輻鍂LF<EFBFBD>Z<EFBFBD>蝚?*
|
||||
3. <20>?**<2A>灼docker-entrypoint.sh`銝剜溶<E5899C>䭾<EFBFBD><E4ADBE>仿<EFBFBD>餉<EFBFBD>嚗<EFBFBD>郎<EFBFBD>𦠜<EFBFBD>蝷綽<E89DB7>**
|
||||
**解决方案:**
|
||||
1. ✅ **删除`database.php`末尾的`?>`和所有空行**
|
||||
2. ✅ **创建`.gitattributes`强制PHP文件使用LF换行符**
|
||||
3. ✅ **在`docker-entrypoint.sh`中添加检查逻辑(警告提示)**
|
||||
|
||||
**PHP最佳实践:**
|
||||
- 📌 **配置文件和库文件末尾不应该写`?>`**
|
||||
- <20><> 餈蹱糓PHP摰䀹䲮<E480B9>刻<EFBFBD>嚗𣬚鍂鈭𡡞俈甇X錰撠曄征銵峕情<E5B395>栞<EFBFBD><E6A09E>?
|
||||
- 📌 这是PHP官方推荐,用于防止末尾空行污染输出
|
||||
- 📌 REDCap官方源码都遵循此规范
|
||||
|
||||
---
|
||||
@@ -103,7 +103,7 @@ WHERE field_name = 'redcap_base_url';
|
||||
|
||||
### 密码重置工具
|
||||
|
||||
<EFBFBD>𥕦遣鈭<EFBFBD>scripts/create-redcap-password.php`嚗𣬚鍂鈭𡡞<EFBFBD>蝵娜EDCap<EFBFBD>冽<EFBFBD>撖<EFBFBD><EFBFBD>嚗?
|
||||
创建了`scripts/create-redcap-password.php`,用于重置REDCap用户密码:
|
||||
|
||||
```bash
|
||||
# 使用方法
|
||||
@@ -111,54 +111,54 @@ docker cp scripts/create-redcap-password.php redcap-apache:/tmp/
|
||||
docker exec redcap-apache php /tmp/create-redcap-password.php
|
||||
```
|
||||
|
||||
**瘜冽<EFBFBD>嚗?* 甇方<E79487><E696B9>砌<EFBFBD><E7A08C>其<EFBFBD>撘<EFBFBD><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD>煺漣<E785BA>臬<EFBFBD>摨𠉛<E691A8><F0A0899B>具<EFBFBD>?
|
||||
**注意:** 此脚本仅用于开发环境!生产环境应禁用。
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F><>蝏<EFBFBD>&霈?
|
||||
## ✅ 最终确认
|
||||
|
||||
### REDCap系统是安全的
|
||||
|
||||
**<EFBFBD>滩<EFBFBD>蝏栞捏嚗?*
|
||||
1. <EFBFBD>?**REDCap摰䀹䲮皞鞟<EFBFBD>嚗?5.8.0<EFBFBD><EFBFBD>𧋦嚗峕㺭<EFBFBD><EFBFBD>葵PHP<EFBFBD><EFBFBD>辣嚗厰<EFBFBD><EFBFBD>航<EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
|
||||
2. <EFBFBD>?**摰䀹䲮<E480B9><E4B2AE>辣<EFBFBD>怠偏<E680A0>賣瓷<E8B3A3>头?>`嚗䔶<EFBFBD>摮睃銁CRLF瘙⊥<EFBFBD><EFBFBD>桅<EFBFBD>**
|
||||
3. <20>?**<2A>桅<EFBFBD>隞<EFBFBD><E99A9E><EFBFBD>其<EFBFBD><E585B6>睲賑<E79DB2>𥕦遣<F0A595A6><E981A3><EFBFBD>蝵格<E89DB5>隞跆database.php`**
|
||||
4. <20>?**銝<><E98A9D>虫耨憭㵪<E686AD>銝滢<E98A9D><E6BBA2>匧<EFBFBD>隞𣇉掩隡潮䔮憸?*
|
||||
**重要结论:**
|
||||
1. ✅ **REDCap官方源码(15.8.0版本,数千个PHP文件)都是规范的**
|
||||
2. ✅ **官方文件末尾都没有`?>`,不存在CRLF污染问题**
|
||||
3. ✅ **问题仅存在于我们创建的配置文件`database.php`**
|
||||
4. ✅ **一旦修复,不会有其他类似问题**
|
||||
|
||||
**撉諹<EFBFBD>霂<EFBFBD>旿嚗?*
|
||||
**验证证据:**
|
||||
```bash
|
||||
# REDCap官方index.php末尾(规范)
|
||||
tail -c 20 /var/www/html/redcap/redcap_v15.8.0/index.php | xxd
|
||||
00000000: 656e 6572 616c 2f66 6f6f 7465 722e 7068 eneral/footer.ph
|
||||
00000010: 7027 3b0a p';.
|
||||
# <EFBFBD>怠偏<EFBFBD>芣<EFBFBD> '; <20>峕揢銵𣬚泵嚗峕瓷<E5B395>?>
|
||||
# 末尾只有 '; 和换行符,没有?>
|
||||
|
||||
# REDCap官方Authentication.php末尾(规范)
|
||||
tail -c 30 /var/www/html/redcap/redcap_v15.8.0/Classes/Authentication.php | xxd
|
||||
00000000: 6c2c 205b 2475 7365 7269 645d 2929 203e l, [$userid])) >
|
||||
00000010: 2030 3b0a 0909 7d0a 097d 0a0a 7d0a 0;...}..}..}.
|
||||
# <EFBFBD>怠偏<EFBFBD>芣<EFBFBD> } <20>峕揢銵𣬚泵嚗峕瓷<E5B395>?>
|
||||
# 末尾只有 } 和换行符,没有?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 经验总结
|
||||
|
||||
### 1. Docker頝典像<EFBFBD>唳釣<EFBFBD>譍<EFBFBD>憿?
|
||||
### 1. Docker跨平台注意事项
|
||||
|
||||
**Windows + Docker + Linux容器组合会暴露文件格式问题:**
|
||||
- Windows默认CRLF (`\r\n`)
|
||||
- Linux默认LF (`\n`)
|
||||
- Git的`autocrlf`设置可能自动转换
|
||||
- 雿輻鍂`.gitattributes`<EFBFBD>曉<EFBFBD><EFBFBD>批<EFBFBD><EFBFBD>Z<EFBFBD>蝚?
|
||||
- 使用`.gitattributes`显式控制换行符
|
||||
|
||||
### 2. PHP<EFBFBD>滨蔭<EFBFBD><EFBFBD>辣<EFBFBD><EFBFBD>雿喳<EFBFBD>頝?
|
||||
### 2. PHP配置文件最佳实践
|
||||
|
||||
```php
|
||||
<?php
|
||||
// 配置代码...
|
||||
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁏<E59A97>蝏𤘪<E89D8F><F0A498AA><EFBFBD>倌<EFBFBD>𣬚征銵?
|
||||
// ❌ 错误:有结束标签和空行
|
||||
?>
|
||||
|
||||
|
||||
@@ -168,12 +168,12 @@ tail -c 30 /var/www/html/redcap/redcap_v15.8.0/Classes/Authentication.php | xxd
|
||||
<?php
|
||||
// 配置代码...
|
||||
|
||||
// <EFBFBD>?甇<>&嚗𡁏瓷<F0A1818F>厩<EFBFBD><E58EA9><EFBFBD><EFBFBD>蝑?
|
||||
// ✅ 正确:没有结束标签
|
||||
```
|
||||
|
||||
### 3. REDCap<EFBFBD>函蔡璉<EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>?
|
||||
### 3. REDCap部署检查清单
|
||||
|
||||
- [ ] Apache DocumentRoot銝𦻓ase URL銝<EFBFBD><EFBFBD>?
|
||||
- [ ] Apache DocumentRoot与Base URL一致
|
||||
- [ ] 禁用压缩模块(开发环境)
|
||||
- [ ] `database.php`末尾无`?>`
|
||||
- [ ] 文件换行符统一为LF
|
||||
@@ -182,22 +182,22 @@ tail -c 30 /var/www/html/redcap/redcap_v15.8.0/Classes/Authentication.php | xxd
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>𡒊賒<F0A1928A>函蔡<E587BD>啁<EFBFBD>鈭抒㴓憓?
|
||||
## 🚀 后续部署到生产环境
|
||||
|
||||
**<EFBFBD>砍𧑐Docker撘<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD>歇撉諹<EFBFBD><EFBFBD>朞<EFBFBD>嚗<EFBFBD>虾隞亙<EFBFBD><EFBFBD>刻<EFBFBD>蝘餃<EFBFBD><EFBFBD>輸<EFBFBD>鈭䫿CS嚗?*
|
||||
**本地Docker开发环境已验证通过,可以安全迁移到阿里云ECS:**
|
||||
|
||||
1. <20>?雿輻鍂<E8BCBB>詨<EFBFBD><E8A9A8><EFBFBD>Dockerfile.redcap`<60><>遣<EFBFBD>𨅯<EFBFBD>
|
||||
2. <20>?靽格㺿`database.php`餈墧𦻖<EFBFBD>訌DS
|
||||
3. <20>?<3F>煺漣<E785BA>臬<EFBFBD><E887AC>臭誑<E887AD>舐鍂Gzip<69>讠憬嚗<E686AC>蝙<EFBFBD>沐ginx<6E>滚<EFBFBD>隞<EFBFBD><E99A9E>嚗?
|
||||
4. <20>?<3F><><EFBFBD>厰<EFBFBD>蝵格<E89DB5>隞嗅歇蝏讛<E89D8F>撉諹<E69289>嚗䔶<E59A97>隡𡁏<E99AA1>CRLF<4C>桅<EFBFBD>
|
||||
1. ✅ 使用相同的`Dockerfile.redcap`构建镜像
|
||||
2. ✅ 修改`database.php`连接到RDS
|
||||
3. ✅ 生产环境可以启用Gzip压缩(使用Nginx反向代理)
|
||||
4. ✅ 所有配置文件已经过验证,不会有CRLF问题
|
||||
|
||||
**<EFBFBD>芣䔉銝漤<EFBFBD>閬<EFBFBD><EFBFBD>𣂷葵<EFBFBD>埝䰻REDCap<EFBFBD><EFBFBD>辣嚗<EFBFBD><EFBFBD>銝箏<EFBFBD><EFBFBD>嫣誨<EFBFBD><EFBFBD>糓閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?
|
||||
**未来不需要逐个排查REDCap文件,因为官方代码是规范的!** ✨
|
||||
|
||||
---
|
||||
|
||||
## 📞 联系方式
|
||||
|
||||
憒<EFBFBD><EFBFBD><EFBFBD>桅<EFBFBD>嚗諹窈<EFBFBD>亦<EFBFBD>嚗?
|
||||
如有问题,请查看:
|
||||
- REDCap官方文档:https://projectredcap.org/
|
||||
- <20>函蔡<E587BD>寞<EFBFBD><E5AF9E><EFBFBD>﹝嚗䫤docs/03-REDCap<EFBFBD>砍𧑐Docker撘<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>蝵脫䲮獢?md`
|
||||
- 部署方案文档:`docs/03-REDCap本地Docker开发环境部署方案.md`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user