refactor: 优化ViewModel和工具类
- 优化AuthViewModel认证ViewModel - 优化MyMemoirViewModel回忆录ViewModel - 扩展TextUtils工具类
This commit is contained in:
@@ -338,16 +338,17 @@ class AuthViewModel(private val context: Context) : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码登录
|
* 验证码登录/注册(统一接口)
|
||||||
|
* 如果用户不存在,会自动注册(需要提供nickname)
|
||||||
*/
|
*/
|
||||||
fun loginWithSms(phone: String, code: String, agreedToTerms: Boolean) {
|
fun loginWithSms(phone: String, code: String, agreedToTerms: Boolean, nickname: String? = null) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_isLoading.value = true
|
_isLoading.value = true
|
||||||
_errorMessage.value = null
|
_errorMessage.value = null
|
||||||
_successMessage.value = null
|
_successMessage.value = null
|
||||||
_operationResult.value = null
|
_operationResult.value = null
|
||||||
|
|
||||||
val result = authService.loginWithSms(phone, code, agreedToTerms)
|
val result = authService.loginWithSms(phone, code, agreedToTerms, nickname)
|
||||||
|
|
||||||
result.fold(
|
result.fold(
|
||||||
onSuccess = { tokenResponse ->
|
onSuccess = { tokenResponse ->
|
||||||
@@ -365,21 +366,35 @@ class AuthViewModel(private val context: Context) : ViewModel() {
|
|||||||
|
|
||||||
// 显示成功消息
|
// 显示成功消息
|
||||||
val userNickname = _currentUser.value?.nickname ?: "用户"
|
val userNickname = _currentUser.value?.nickname ?: "用户"
|
||||||
_successMessage.value = "登录成功!"
|
val isNewUser = nickname != null && nickname.isNotBlank()
|
||||||
|
_successMessage.value = if (isNewUser) "注册成功!" else "登录成功!"
|
||||||
_operationResult.value = OperationResult(
|
_operationResult.value = OperationResult(
|
||||||
success = true,
|
success = true,
|
||||||
message = "登录成功",
|
message = if (isNewUser) "注册成功" else "登录成功",
|
||||||
details = "欢迎回来,${userNickname}!正在跳转..."
|
details = if (isNewUser) {
|
||||||
|
"账号已创建,欢迎加入岁月史书!正在跳转..."
|
||||||
|
} else {
|
||||||
|
"欢迎回来,${userNickname}!正在跳转..."
|
||||||
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onFailure = { exception ->
|
onFailure = { exception ->
|
||||||
val errorMsg = exception.message ?: "登录失败"
|
val errorMsg = exception.message ?: "登录失败"
|
||||||
_errorMessage.value = errorMsg
|
_errorMessage.value = errorMsg
|
||||||
_isLoggedIn.value = false
|
_isLoggedIn.value = false
|
||||||
|
|
||||||
|
// 检查是否是首次登录需要昵称的错误
|
||||||
|
val needsNickname = errorMsg.contains("首次登录需要设置昵称") ||
|
||||||
|
errorMsg.contains("需要设置昵称")
|
||||||
|
|
||||||
_operationResult.value = OperationResult(
|
_operationResult.value = OperationResult(
|
||||||
success = false,
|
success = false,
|
||||||
message = "登录失败",
|
message = if (needsNickname) "需要设置昵称" else "登录失败",
|
||||||
details = errorMsg
|
details = if (needsNickname) {
|
||||||
|
"这是您首次登录,请设置一个昵称"
|
||||||
|
} else {
|
||||||
|
errorMsg
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class MyMemoirViewModel(
|
|||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
val chapters = chapterRepository.getAllChapters()
|
val chapters = chapterRepository.getAllChapters()
|
||||||
|
val chapterDtos = MutableStateFlow<List<com.huaga.life_echo.network.models.ChapterDto>>(emptyList())
|
||||||
val selectedChapter = MutableStateFlow<Chapter?>(null)
|
val selectedChapter = MutableStateFlow<Chapter?>(null)
|
||||||
val isLoading = MutableStateFlow(false)
|
val isLoading = MutableStateFlow(false)
|
||||||
val error = MutableStateFlow<String?>(null)
|
val error = MutableStateFlow<String?>(null)
|
||||||
@@ -64,9 +65,12 @@ class MyMemoirViewModel(
|
|||||||
try {
|
try {
|
||||||
val result = apiService.getChapters()
|
val result = apiService.getChapters()
|
||||||
result.fold(
|
result.fold(
|
||||||
onSuccess = { chapterDtos ->
|
onSuccess = { chapterDtosFromApi ->
|
||||||
|
// 保存ChapterDto(包含images信息)
|
||||||
|
chapterDtos.value = chapterDtosFromApi
|
||||||
|
|
||||||
// 转换为本地Chapter实体并保存
|
// 转换为本地Chapter实体并保存
|
||||||
val chapters = chapterDtos.map { dto ->
|
val chapters = chapterDtosFromApi.map { dto ->
|
||||||
Chapter(
|
Chapter(
|
||||||
id = dto.id,
|
id = dto.id,
|
||||||
title = dto.title,
|
title = dto.title,
|
||||||
|
|||||||
@@ -65,4 +65,36 @@ object TextUtils {
|
|||||||
val quotePattern = Regex("""["'](.*?)["']""")
|
val quotePattern = Regex("""["'](.*?)["']""")
|
||||||
return quotePattern.findAll(text).map { it.groupValues[1] }.toList()
|
return quotePattern.findAll(text).map { it.groupValues[1] }.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除图片占位符
|
||||||
|
* 如果没有图片,移除所有{{{{IMAGE:...}}}}和{{IMAGE:...}}格式的占位符
|
||||||
|
* 同时确保每个段落之间有空行
|
||||||
|
* @param content 原始内容
|
||||||
|
* @param hasImages 是否有图片
|
||||||
|
* @return 处理后的内容
|
||||||
|
*/
|
||||||
|
fun removeImagePlaceholders(content: String?, hasImages: Boolean = false): String {
|
||||||
|
if (content.isNullOrBlank()) return ""
|
||||||
|
|
||||||
|
var processed = if (!hasImages) {
|
||||||
|
// 移除所有{{{{IMAGE:...}}}}格式的占位符(四个大括号)
|
||||||
|
content.replace(Regex("\\{\\{\\{\\{IMAGE:[^}]+\\}\\}\\}\\}"), "")
|
||||||
|
// 移除所有{{IMAGE:...}}格式的占位符(两个大括号)
|
||||||
|
.replace(Regex("\\{\\{IMAGE:[^}]+\\}\\}"), "")
|
||||||
|
.trim()
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保每个段落之间有空行
|
||||||
|
// 将单个换行符(非空行后跟非空行)替换为双换行符
|
||||||
|
// 但保留已有的双换行符或更多换行符
|
||||||
|
processed = processed.replace(Regex("([^\n\\r])\\r?\\n([^\n\\r])"), "$1\n\n$2")
|
||||||
|
|
||||||
|
// 清理多余的空行(连续3个或以上的换行符替换为2个)
|
||||||
|
processed = processed.replace(Regex("\n{3,}"), "\n\n")
|
||||||
|
|
||||||
|
return processed.trim()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user