临时群

This commit is contained in:
fengge 2026-07-08 11:03:54 +08:00
parent 1d615bfafa
commit 2e1f115c19
4 changed files with 162 additions and 68 deletions

View File

@ -273,25 +273,17 @@ public class CallBackResolution {
// 处理临时呼叫页面逻辑
if (code == 1) {
// 临时呼叫临时群组 打开临时呼叫页面
try {
android.content.Intent intent = new android.content.Intent(
com.stand.standapp.MyApplication.getAppInstance(),
com.stand.standapp.TempCallActivity.class
);
// 从84消息中提取临时群名称格式为"临时呼叫XXX"
android.content.Context context = com.stand.standapp.MyApplication.getAppInstance();
String account = com.stand.standapp.AppConfig.getSavedUsername(context);
String token = com.stand.standapp.AppConfig.getAccessToken(context);
String tempGroupName = "临时会话";
if (tempTxt.startsWith("临时呼叫") && tempTxt.length() > "临时呼叫".length()) {
tempGroupName = tempTxt.substring("临时呼叫".length());
}
intent.putExtra("group_name", tempGroupName);
intent.addFlags(
android.content.Intent.FLAG_ACTIVITY_NEW_TASK |
android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP
);
com.stand.standapp.MyApplication.getAppInstance().startActivity(intent);
com.stand.standapp.TempCallActivity.checkAndHandleTempGroup(context, account, token, tempGroupName);
} catch (Exception e) {
Timber.tag(TAG).e( "Failed to open TempCallActivity: " + e.getMessage());
Timber.tag(TAG).e(e, "Failed to check initiator status and handle TempCallActivity");
}
} else if (code == 0) {
// 退出临时呼叫 关闭临时呼叫页面

View File

@ -12,6 +12,7 @@ object AppConfig {
private const val KEY_PASSWORD = "saved_password"
private const val KEY_ACCESS_TOKEN = "access_token"
private const val KEY_LAST_GROUP_ID = "last_group_id"
private const val KEY_USER_ID = "user_id"
// 默认配置
const val DEFAULT_SERVER_URL = "https://template.gyouzhe.com"
@ -55,6 +56,7 @@ object AppConfig {
getPrefs(context).edit().putBoolean(KEY_REMEMBER_LOGIN, remember).apply()
}
@JvmStatic
fun getSavedUsername(context: Context): String {
return getPrefs(context).getString(KEY_USERNAME, "") ?: ""
}
@ -71,6 +73,7 @@ object AppConfig {
getPrefs(context).edit().putString(KEY_PASSWORD, password).apply()
}
@JvmStatic
fun getAccessToken(context: Context): String {
return getPrefs(context).getString(KEY_ACCESS_TOKEN, "") ?: ""
}
@ -86,4 +89,14 @@ object AppConfig {
fun setLastGroupId(context: Context, groupId: String) {
getPrefs(context).edit().putString(KEY_LAST_GROUP_ID, groupId).apply()
}
@JvmStatic
fun getSavedUserId(context: Context): String {
return getPrefs(context).getString(KEY_USER_ID, "") ?: ""
}
@JvmStatic
fun setSavedUserId(context: Context, userId: String) {
getPrefs(context).edit().putString(KEY_USER_ID, userId).apply()
}
}

View File

@ -158,6 +158,14 @@ class LoginActivity : AppCompatActivity() {
val accessToken = data?.optString("access_token", "") ?: ""
AppConfig.setAccessToken(this@LoginActivity, accessToken)
// 提取并保存当前用户的 userId
val userObj = data?.optJSONObject("user")
val userId = userObj?.optString("userId", "")?.takeIf { it.isNotEmpty() }
?: userObj?.optString("id", "")?.takeIf { it.isNotEmpty() }
?: data?.optString("userId", "")?.takeIf { it.isNotEmpty() }
?: data?.optString("id", "") ?: ""
AppConfig.setSavedUserId(this@LoginActivity, userId)
Toast.makeText(applicationContext, "登录成功", Toast.LENGTH_SHORT).show()
// 获取独立的 PTT 账号并初始化
@ -262,57 +270,7 @@ class LoginActivity : AppCompatActivity() {
private fun checkTempGroup(account: String, loginData: org.json.JSONObject?) {
val accessToken = loginData?.optString("access_token", "") ?: return
if (accessToken.isEmpty()) return
val serverUrl = AppConfig.getServerUrl(this)
val url = "$serverUrl/api/external/ptt/user/groups?account=$account"
val request = Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer $accessToken")
.get()
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Timber.tag("TempGroup").w(e, "检查临时群组失败")
}
override fun onResponse(call: Call, response: Response) {
try {
val body = response.body?.string() ?: return
val json = JSONObject(body)
val dataObj = json.optJSONObject("data")
val list = dataObj?.optJSONArray("data") ?: return
for (i in 0 until list.length()) {
val group = list.optJSONObject(i) ?: continue
val gtype = group.optString("gtype", "")
if (gtype == "2") {
val gname = group.optString("gname", "临时群组")
val gid = group.optString("gid", "")
Timber.tag("TempGroup").d("发现临时群组: $gname")
// 打开临时呼叫页面
val appCtx = com.stand.standapp.MyApplication.getAppInstance()
val intent = android.content.Intent(
appCtx,
TempCallActivity::class.java
)
intent.putExtra("group_name", gname)
intent.putExtra("gid", gid)
intent.addFlags(
android.content.Intent.FLAG_ACTIVITY_NEW_TASK or
android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK or
android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
)
appCtx.startActivity(intent)
break
}
}
} catch (e: Exception) {
Timber.tag("TempGroup").e(e, "解析临时群组响应失败")
}
}
})
TempCallActivity.checkAndHandleTempGroup(this, account, accessToken)
}
private fun initPttWithAccount(username: String, accessToken: String) {

View File

@ -36,7 +36,7 @@ class TempCallActivity : AppCompatActivity() {
@Volatile
var isMinimized = false
private set
internal set
// 存储当前临时群组名称,用于恢复时传递
@Volatile
@ -58,9 +58,11 @@ class TempCallActivity : AppCompatActivity() {
val intent = android.content.Intent(
com.stand.standapp.MyApplication.getAppInstance(),
TempCallActivity::class.java
)
intent.putExtra("group_name", currentGroupName)
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
).apply {
putExtra("group_name", currentGroupName)
putExtra("gid", currentTempGroupId)
addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
}
com.stand.standapp.MyApplication.getAppInstance().startActivity(intent)
}
}
@ -85,6 +87,134 @@ class TempCallActivity : AppCompatActivity() {
MainActivity.executeJs("onTempCallStateChanged('destroyed')")
MainActivity.executeJs("if(window.endPullGroupLock){ window.endPullGroupLock(); }")
}
@JvmStatic
@JvmOverloads
fun checkAndHandleTempGroup(
context: android.content.Context,
account: String,
token: String,
groupNameFromCall: String? = null,
targetGid: String? = null
) {
if (token.isEmpty()) {
Timber.tag("TempGroupCheck").w("token is empty, skip check")
return
}
val serverUrl = AppConfig.getServerUrl(context)
val url = "$serverUrl/api/vid-pull-record/my-list"
val request = okhttp3.Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer $token")
.get()
.build()
com.stand.standapp.net.NetworkModule.defaultClient.newCall(request).enqueue(object : okhttp3.Callback {
override fun onFailure(call: okhttp3.Call, e: java.io.IOException) {
Timber.tag("TempGroupCheck").e(e, "获取拉动记录失败")
if (groupNameFromCall != null) {
startTempCallActivity(context, groupNameFromCall, targetGid ?: "")
}
}
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
try {
val body = response.body?.string() ?: return
val json = org.json.JSONObject(body)
if (json.optInt("code", -1) == 0) {
val dataArray = json.optJSONArray("data")
var matchedRecord: org.json.JSONObject? = null
if (dataArray != null && dataArray.length() > 0) {
// 1. 如果指定了 GID优先按 GID 匹配
if (targetGid != null && targetGid.isNotEmpty()) {
for (i in 0 until dataArray.length()) {
val record = dataArray.optJSONObject(i) ?: continue
val pocGid = record.optString("pocGid", "")
if (pocGid == targetGid) {
matchedRecord = record
break
}
}
}
// 2. 如果未指定 GID 或未匹配到,且有传入的呼叫群组名称,按名称匹配
if (matchedRecord == null && groupNameFromCall != null && groupNameFromCall.isNotEmpty() && groupNameFromCall != "临时会话") {
for (i in 0 until dataArray.length()) {
val record = dataArray.optJSONObject(i) ?: continue
val pullTitle = record.optString("pullTitle", "")
if (pullTitle.contains(groupNameFromCall) || groupNameFromCall.contains(pullTitle)) {
matchedRecord = record
break
}
}
}
// 3. 如果仍未匹配到,默认使用最新的一条记录
if (matchedRecord == null) {
matchedRecord = dataArray.optJSONObject(0)
}
}
if (matchedRecord != null) {
val pocGid = matchedRecord.optString("pocGid", "")
val pullTitle = matchedRecord.optString("pullTitle", "临时会话")
val createBy = matchedRecord.optString("createBy", "")
val currentUserId = AppConfig.getSavedUserId(context)
val isInitiator = currentUserId.isNotEmpty() && currentUserId == createBy
Timber.tag("TempGroupCheck").d("匹配拉动记录成功: title=$pullTitle, pocGid=$pocGid, createBy=$createBy, isInitiator=$isInitiator")
if (isInitiator) {
isMinimized = true
currentTempGroupId = pocGid
currentGroupName = pullTitle
MainActivity.executeJs("onTempCallStateChanged('minimized')")
if (pocGid.isNotEmpty()) {
MainActivity.executeJs("if(window.startPullGroupLock){ window.startPullGroupLock('$pocGid'); }")
}
} else {
startTempCallActivity(context, pullTitle, pocGid)
}
} else {
if (groupNameFromCall != null) {
startTempCallActivity(context, groupNameFromCall, targetGid ?: "")
}
}
} else {
if (groupNameFromCall != null) {
startTempCallActivity(context, groupNameFromCall, targetGid ?: "")
}
}
} catch (e: Exception) {
Timber.tag("TempGroupCheck").e(e, "解析拉动记录响应失败")
if (groupNameFromCall != null) {
startTempCallActivity(context, groupNameFromCall, targetGid ?: "")
}
}
}
})
}
@JvmStatic
private fun startTempCallActivity(context: android.content.Context, gname: String, gid: String) {
try {
val intent = android.content.Intent(context, TempCallActivity::class.java).apply {
putExtra("group_name", gname)
putExtra("gid", gid)
addFlags(
android.content.Intent.FLAG_ACTIVITY_NEW_TASK or
android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK or
android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
)
}
context.startActivity(intent)
} catch (e: Exception) {
Timber.tag("TempGroupCheck").e(e, "Failed to start TempCallActivity")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
@ -106,6 +236,7 @@ class TempCallActivity : AppCompatActivity() {
val gid = intent.getStringExtra("gid") ?: ""
currentGroupName = groupName
if (gid.isNotEmpty()) {
currentTempGroupId = gid
MainActivity.executeJs("if(window.startPullGroupLock){ window.startPullGroupLock('$currentTempGroupId'); }")
}
findViewById<TextView>(R.id.tv_group_name).text = groupName