This commit is contained in:
xiao12feng 2025-12-14 15:34:28 +08:00
parent 618e6bd4c7
commit e7c1563f15
3 changed files with 502 additions and 3 deletions

View File

@ -0,0 +1,68 @@
-- =====================================================
-- 删除信息编号大于100的用户及其所有相关数据
-- 同时清空所有测评记录和报告
-- 执行前请先备份数据库!
-- =====================================================
-- ==================== 第一部分:清空所有测评数据 ====================
-- 1. 删除所有预警记录(关联测评的)
DELETE FROM psy_warning WHERE assessment_id IS NOT NULL;
-- 2. 删除所有测评报告
DELETE FROM psy_assessment_report;
-- 3. 删除所有测评答案
DELETE FROM psy_assessment_answer;
-- 4. 删除所有测评记录
DELETE FROM psy_assessment;
-- 5. 删除所有问卷答案详情
DELETE FROM psy_questionnaire_answer_detail;
-- 6. 删除所有问卷答题记录
DELETE FROM psy_questionnaire_answer;
-- ==================== 第二部分:删除信息编号>100的用户 ====================
-- 7. 预览要删除的用户档案
SELECT p.profile_id, p.user_id, u.nick_name AS user_name, p.info_number
FROM psy_user_profile p
LEFT JOIN sys_user u ON p.user_id = u.user_id
WHERE CAST(p.info_number AS UNSIGNED) > 100;
-- 8. 删除预警记录通过user_id关联
DELETE FROM psy_warning WHERE user_id IN (
SELECT user_id FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100 AND user_id IS NOT NULL
);
-- 9. 删除量表权限
DELETE FROM psy_scale_permission WHERE user_id IN (
SELECT user_id FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100 AND user_id IS NOT NULL
);
-- 10. 删除用户角色关联
DELETE FROM sys_user_role WHERE user_id IN (
SELECT user_id FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100 AND user_id IS NOT NULL
);
-- 11. 删除用户岗位关联
DELETE FROM sys_user_post WHERE user_id IN (
SELECT user_id FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100 AND user_id IS NOT NULL
);
-- 12. 删除系统用户
DELETE FROM sys_user WHERE user_id IN (
SELECT user_id FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100 AND user_id IS NOT NULL
);
-- 13. 删除用户档案
DELETE FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100;
-- ==================== 第三部分:验证结果 ====================
SELECT COUNT(*) AS remaining_profiles FROM psy_user_profile WHERE CAST(info_number AS UNSIGNED) > 100;
SELECT COUNT(*) AS total_profiles FROM psy_user_profile;
SELECT COUNT(*) AS total_assessments FROM psy_assessment;
SELECT COUNT(*) AS total_reports FROM psy_assessment_report;

View File

@ -159,7 +159,7 @@ export default {
//
if (isAdmin) {
//
listScale({ status: '0', includeQuestionnaire: true }).then(response => {
listScale({ status: '0', includeQuestionnaire: true, pageNum: 1, pageSize: 1000 }).then(response => {
this.scaleList = response.rows.filter(scale => scale.itemCount > 0);
// URLscaleId
if (this.form.scaleId) {
@ -195,7 +195,7 @@ export default {
console.error("用户ID无效:", userId);
// userId
console.warn("用户ID无效尝试加载所有量表和问卷");
listScale({ status: '0', includeQuestionnaire: true }).then(response => {
listScale({ status: '0', includeQuestionnaire: true, pageNum: 1, pageSize: 1000 }).then(response => {
this.scaleList = response.rows.filter(scale => scale.itemCount > 0);
// URLscaleId
if (this.form.scaleId) {
@ -231,7 +231,7 @@ export default {
module.getUserScaleIds(userId).then(permissionResponse => {
const allowedScaleIds = permissionResponse.data || [];
//
listScale({ status: '0', includeQuestionnaire: true }).then(response => {
listScale({ status: '0', includeQuestionnaire: true, pageNum: 1, pageSize: 1000 }).then(response => {
this.scaleList = response.rows.filter(scale => {
if (scale.itemCount === 0) return false;
//

View File

@ -0,0 +1,431 @@
# 🎯 内网环境ANR问题彻底解决方案
## 问题诊断
### 原始问题
- App在内网环境下朗读按钮显示**灰色**disabled
- 点击无反应,无法使用朗读功能
- 一段时间后出现**ANR**Application Not Responding
- 应用被系统强制关闭
### 根本原因
1. **前端检测逻辑不完整**:只检查 `window.AndroidTTS` 是否存在,未调用 `isAvailable()` 方法
2. **旧实现依赖外网**使用百度在线TTS API (`https://fanyi.baidu.com/gettts`)
3. **内网无法访问外网**:网络请求超时导致主线程阻塞
4. **导致ANR**:长时间等待响应,系统判定应用无响应
---
## ✅ 解决方案
### 核心改进
1. **使用Android原生TextToSpeech引擎**:完全离线,不需要网络
2. **修改前端检测逻辑**:正确调用 `isAvailable()` 方法检查TTS状态
3. **添加延迟重试机制**处理TTS异步初始化的时序问题
4. **自动降级策略**如果原生TTS不可用自动切换到浏览器TTS
---
## 📝 已修改的文件
### Android代码
#### 1. `TtsHelper.java` - 使用原生TTS引擎
**文件位置**`xinli-App/app/src/main/java/com/xinli/app/TtsHelper.java`
**核心改动**
```java
// 使用Android原生TextToSpeech引擎
private TextToSpeech tts;
private void initTts() {
tts = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
// 设置中文语言
int result = tts.setLanguage(Locale.CHINESE);
isReady = true;
Log.i(TAG, "✅ Android原生TTS初始化成功离线");
}
}
});
}
@JavascriptInterface
public void speak(String text) {
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
}
```
**特性**
- ✅ 完全离线工作
- ✅ 使用系统内置TTS引擎
- ✅ 支持中文朗读
- ✅ 无网络超时风险
- ✅ 不会导致ANR
### 前端代码
#### 2. `assessment/taking.vue` - 测评答题页面
**文件位置**`xinli-ui/src/views/psychology/assessment/taking.vue`
**核心改动**
```javascript
initTts() {
// 检测 Android App 环境
if (window.AndroidTTS && typeof window.AndroidTTS.isAvailable === 'function') {
// 调用 isAvailable() 方法检查 TTS 是否真的可用
if (window.AndroidTTS.isAvailable()) {
this.isTtsSupported = true;
this.useAndroidTts = true;
console.log('✅ 使用Android原生TTS');
return;
} else {
// TTS 可能还在初始化中,延迟重试
console.log('⏳ Android TTS尚未就绪延迟检查...');
setTimeout(() => {
if (window.AndroidTTS && window.AndroidTTS.isAvailable()) {
this.isTtsSupported = true;
this.useAndroidTts = true;
console.log('✅ Android TTS 已就绪(延迟检测)');
} else {
this.fallbackToBrowserTts();
}
}, 500);
// 先启用按钮,避免用户等待
this.isTtsSupported = true;
return;
}
}
// 浏览器环境
this.fallbackToBrowserTts();
}
```
**特性**
- ✅ 调用 `isAvailable()` 验证TTS可用性
- ✅ 500ms延迟重试处理异步初始化
- ✅ 立即启用按钮,提升用户体验
- ✅ 自动降级到浏览器TTS
#### 3. `questionnaire/taking.vue` - 问卷答题页面
**文件位置**`xinli-ui/src/views/psychology/questionnaire/taking.vue`
**改动**:与测评页面保持一致的检测逻辑
---
## 🚀 部署步骤
### 第1步重新构建前端
```bash
cd c:\Users\Administrator\Desktop\Project\xinli\xinli-ui
npm run build:prod
```
**耗时**约2-5分钟
### 第2步部署前端到服务器
`xinli-ui/dist` 目录的所有文件复制到服务器的Web根目录。
### 第3步打包Android APK
```bash
cd c:\Users\Administrator\Desktop\Project\xinli\xinli-App
.\打包正式版APK.bat
```
**耗时**约3-5分钟
### 第4步查找生成的APK
```bash
.\查找APK.bat
```
APK文件位置
```
xinli-App\app\build\outputs\apk\release\app-release.apk
```
### 第5步部署到设备
#### 重要:必须先卸载旧版本!
**方法1通过手机设置卸载**
1. 设置 → 应用管理 → 找到"心理测评"App
2. 点击"卸载"
**方法2使用ADB命令**
```bash
adb uninstall com.xinli.app
```
#### 安装新版APK
**方法1直接安装**
1. 将APK文件复制到手机
2. 点击文件安装
**方法2使用ADB安装**
```bash
adb install app\build\outputs\apk\release\app-release.apk
```
---
## ✅ 验证测试
### 测试清单
#### 基础功能测试
- [ ] App能正常启动无崩溃
- [ ] 能正常登录
- [ ] 进入答题页面正常
#### TTS功能测试
- [ ] 朗读按钮**不是灰色**(可点击)
- [ ] 点击"朗读全部"能听到声音
- [ ] 点击"朗读题干"能听到声音
- [ ] 点击选项旁的朗读按钮能听到声音
- [ ] 可以正常停止朗读
- [ ] 切换题目后朗读功能正常
#### ANR问题测试
- [ ] **没有出现"应用无响应"对话框**
- [ ] 长时间使用不会卡死
- [ ] 快速点击朗读按钮不会崩溃
### 查看日志(可选)
使用ADB查看TTS日志
```bash
adb logcat | findstr TtsHelper
```
**预期日志**
```
TtsHelper: ✅ Android原生TTS初始化成功离线
TtsHelper: isAvailable: true
TtsHelper: ✅ 开始朗读: ...
```
**前端控制台日志**
```
✅ 使用Android原生TTS
```
```
⏳ Android TTS尚未就绪延迟检查...
✅ Android TTS 已就绪(延迟检测)
```
---
## 🔍 故障排除
### 问题1按钮仍然是灰色
**原因**未卸载旧版App代码未更新
**解决**
1. 完全卸载旧版App
2. 清除应用数据
3. 重新安装新APK
4. 重启App
### 问题2没有声音
**检查项**
1. **手机媒体音量**确保不是0注意不是铃声音量
2. **TTS引擎**检查系统是否安装了中文TTS引擎
- 设置 → 辅助功能 → 文字转语音
- 确认有可用的TTS引擎
3. **查看日志**:运行 `adb logcat | findstr TTS` 查看错误信息
**改善音质**
- 在手机设置中安装高质量TTS引擎
- 推荐Google文字转语音引擎
### 问题3仍然出现ANR
**检查**
1. 确认安装的是新版APK查看APK生成时间
2. 确认前端代码已更新检查dist目录修改时间
3. 查看日志确认使用的是原生TTS
```bash
adb logcat | findstr "Android原生TTS"
```
### 问题4部分设备不支持中文TTS
**解决**
1. 引导用户安装中文TTS引擎
2. 或在App中集成离线TTS SDK如讯飞、百度
---
## 📊 修复对比
| 项目 | 修复前 | 修复后 |
|------|--------|--------|
| **朗读按钮状态** | ❌ 灰色禁用 | ✅ 正常可用 |
| **网络依赖** | ❌ 需要外网访问百度API | ✅ 完全离线 |
| **ANR问题** | ❌ 内网环境会ANR | ✅ 不会ANR |
| **TTS引擎** | ❌ 在线API | ✅ Android原生引擎 |
| **音质** | 一般百度API | 良好(取决于设备) |
| **检测逻辑** | ❌ 只检查对象存在 | ✅ 调用isAvailable()验证 |
| **降级策略** | ❌ 无 | ✅ 自动降级到浏览器TTS |
| **初始化处理** | ❌ 无延迟重试 | ✅ 500ms延迟重试 |
---
## 🎉 技术优势
### 1. 完全离线
- 不依赖任何外部API
- 内网环境正常工作
- 无网络超时风险
### 2. 高可用性
- 使用系统内置TTS引擎
- 双重保障原生TTS + 浏览器TTS
- 异步初始化不阻塞UI
### 3. 用户体验
- 朗读按钮立即可用
- 无需等待网络响应
- 不会出现ANR
### 4. 维护性
- 代码简洁清晰
- 统一的检测逻辑
- 完善的日志输出
---
## 📚 技术细节
### Android原生TTS工作流程
```
1. App启动
2. 初始化TextToSpeech引擎异步
3. onInit回调 → 设置中文语言
4. 设置isReady = true
5. 前端调用isAvailable() → 返回true
6. 前端启用朗读按钮
7. 用户点击朗读 → 调用speak()
8. TTS引擎合成语音并播放
```
### 前端检测流程
```
1. 页面加载 → initTts()
2. 检查window.AndroidTTS是否存在
3. 调用AndroidTTS.isAvailable()
4. 如果返回false → 延迟500ms重试
5. 如果仍然false → 降级到浏览器TTS
6. 设置isTtsSupported = true
7. 朗读按钮可用
```
### 为什么需要延迟重试?
Android的TextToSpeech初始化是**异步**的:
- `new TextToSpeech()` 立即返回
- 实际初始化在后台进行
- `onInit()` 回调可能需要100-500ms
- 前端页面加载可能比TTS初始化更快
**解决方案**
- 第一次检查失败 → 延迟500ms重试
- 同时先启用按钮,提升用户体验
- 用户点击时如果还未就绪 → 内部再延迟重试
---
## ⚠️ 注意事项
### 1. 必须卸载旧版
新APK的签名可能与旧版不同直接安装可能失败或代码不更新。
### 2. 前端也需要更新
只更新APK不够前端检测逻辑也必须更新否则按钮仍然是灰色。
### 3. 设备TTS引擎差异
不同品牌手机的TTS引擎音质有差异
- **华为/小米/OPPO**通常有高质量中文TTS
- **三星**:音质良好
- **低端设备**:可能音质较差或不支持中文
### 4. 浏览器版本不受影响
- Web版PC浏览器继续使用浏览器的Web Speech API
- 修改仅影响Android App
---
## 🔄 未来优化方向
### 短期(可选)
1. **集成高质量离线TTS SDK**
- 讯飞语音SDK
- 百度语音SDK
- 提供更好的音质和更多音色选择
### 长期(可选)
2. **支持语速/音调调节**
- 在App中添加TTS设置界面
- 让用户自定义语音参数
3. **多语言支持**
- 检测题目语言
- 自动切换TTS语言
---
## 📞 技术支持
如果遇到问题:
1. **查看日志**
```bash
adb logcat | findstr "TtsHelper\|AndroidTTS"
```
2. **检查TTS引擎**
- 手机设置 → 辅助功能 → 文字转语音
- 确认有可用的中文TTS引擎
3. **验证安装**
```bash
# 查看已安装App版本
adb shell pm list packages -f | findstr xinli
# 查看APK信息
adb shell dumpsys package com.xinli.app | findstr version
```
---
**修复完成日期**2025-01-27
**测试状态**:✅ 待部署验证
**适用环境**:内网/外网均可使用