From 879ec1ae04b37eb7bf9357903d10acc860d84d5b Mon Sep 17 00:00:00 2001 From: zhujie <leon.zhu@cloudroam.com.cn> Date: 星期二, 15 四月 2025 03:02:18 +0800 Subject: [PATCH] 1 --- app/src/main/res/layout/activity_phone_login.xml | 24 ++++++ app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt | 2 app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt | 7 + app/src/main/res/layout/activity_invitation_main.xml | 50 +++++++++++- app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt | 9 ++ app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt | 1 app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt | 17 ++- app/src/main/java/com/example/firstapp/database/response/UserInfo.kt | 3 app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt | 92 +++++++++++++++++++--- 9 files changed, 177 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt index 8432373..8931e27 100644 --- a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt +++ b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt @@ -31,7 +31,7 @@ binding.apply { // 设置上次登录的手机号 etPhone.setText(PreferencesManager.getLastLoginPhone()) - + btnBack.setOnClickListener { startActivity(Intent(this@PhoneLoginActivity, LoginActivity::class.java)) finish() @@ -43,21 +43,26 @@ viewModel.sendVerificationCode(phone) startCountDown() } else { - Toast.makeText(this@PhoneLoginActivity, - "请输入正确的手机号", Toast.LENGTH_SHORT).show() + Toast.makeText( + this@PhoneLoginActivity, + "请输入正确的手机号", Toast.LENGTH_SHORT + ).show() } } btnLogin.setOnClickListener { val phone = etPhone.text.toString() val code = etCode.text.toString() + val invite = etInvite.text.toString() if (phone.length == 11 && code.length == 6) { // 保存登录的手机号 PreferencesManager.saveLastLoginPhone(phone) - viewModel.login(phone, code) + viewModel.login(phone, code, invite) } else { - Toast.makeText(this@PhoneLoginActivity, - "请输入完整信息", Toast.LENGTH_SHORT).show() + Toast.makeText( + this@PhoneLoginActivity, + "请输入完整信息", Toast.LENGTH_SHORT + ).show() } } } diff --git a/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt b/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt index d76dce6..be8a8b5 100644 --- a/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt +++ b/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt @@ -4,4 +4,5 @@ val username: String, val smsCode: String, val userType: String, + var intevailCode: String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt index dcea53b..5fd4b5b 100644 --- a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt +++ b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt @@ -8,5 +8,6 @@ val contactTel: String, val memberOvertime: String, val memberOverDate: String, - val isMember: Boolean + val isMember: Boolean, + val intervialcode: String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt b/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt index 55d957f..353707d 100644 --- a/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt +++ b/app/src/main/java/com/example/firstapp/ui/invitation/InvitationActivity.kt @@ -1,13 +1,19 @@ package com.example.firstapp.ui.invitation +import android.content.ClipData +import android.content.ClipboardManager import android.content.Context +import android.content.Intent +import android.net.Uri import android.os.Bundle import android.os.Handler import android.os.Looper import android.text.Html import android.util.TypedValue import android.view.View +import android.widget.Button import android.widget.TextView +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller @@ -16,6 +22,7 @@ import com.example.firstapp.adapter.InvitationAdapter import com.example.firstapp.adapter.InvitationRecordAdapter import com.example.firstapp.entity.InvitationRecord +import com.example.firstapp.utils.PreferencesManager import kotlin.math.abs class InvitationActivity : AppCompatActivity() { @@ -51,6 +58,26 @@ //启动轮播 startAutoScroll() + + //分享 + val btnInvite = findViewById<Button>(R.id.btnInvite) + btnInvite.setOnClickListener { + shareImageToWechat() + } + + //邀请码 + val invitationCodeText = findViewById<TextView>(R.id.invitationCodeText) + invitationCodeText.text = "A1B2" + //invitationCodeText.text = formatInvitationCode(PreferencesManager.getInviteCode()); + findViewById<Button>(R.id.copyButton).setOnClickListener { + val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText( + "邀请码", + invitationCodeText.text.toString().replace(" ", "") // 复制时去掉空格 + ) + clipboard.setPrimaryClip(clip) + Toast.makeText(this, "已复制邀请码", Toast.LENGTH_SHORT).show() + } } private fun initViews() { @@ -64,12 +91,12 @@ addRecordListener() } - private fun addSuccessListener(){ + private fun addSuccessListener() { recyclerSuccessView.viewTreeObserver.addOnGlobalLayoutListener { if (recyclerSuccessView.childCount > 0) { // 计算预期高度(60dp转px) val expectedHeight = dpToPx(60f) - if(itemHeight!= expectedHeight){ + if (itemHeight != expectedHeight) { // 修正所有item的高度 for (i in 0 until recyclerSuccessView.childCount) { recyclerSuccessView.getChildAt(i).layoutParams.height = expectedHeight @@ -106,12 +133,12 @@ } } - private fun addRecordListener(){ + private fun addRecordListener() { recyclerRecordView.viewTreeObserver.addOnGlobalLayoutListener { if (recyclerSuccessView.childCount > 0) { // 计算预期高度(60dp转px) val expectedHeight = dpToPx(60f) - if(itemHeight!= expectedHeight){ + if (itemHeight != expectedHeight) { // 修正所有item的高度 for (i in 0 until recyclerSuccessView.childCount) { recyclerSuccessView.getChildAt(i).layoutParams.height = expectedHeight @@ -184,11 +211,11 @@ data.clear() data.addAll( listOf( - InvitationRecord("H****e", "获得了1天会员","已注册"), - InvitationRecord("U****r", "获得了2天会员","已注册"), - InvitationRecord("A****e", "获得了免广告特权","已注册"), - InvitationRecord("B****e", "获得了3天会员","已注册"), - InvitationRecord("C****o", "获得了4天会员","已注册") + InvitationRecord("H****e", "获得了1天会员", "已注册"), + InvitationRecord("U****r", "获得了2天会员", "已注册"), + InvitationRecord("A****e", "获得了免广告特权", "已注册"), + InvitationRecord("B****e", "获得了3天会员", "已注册"), + InvitationRecord("C****o", "获得了4天会员", "已注册") ) ) adapter.notifyDataSetChanged() @@ -198,14 +225,50 @@ recorddata.clear() recorddata.addAll( listOf( - InvitationRecord("M****e", "","未注册"), - InvitationRecord("Q****r", "","已注册"), - InvitationRecord("W****e", "","未注册"), - InvitationRecord("E****e", "","未注册"), - InvitationRecord("R****o", "","已注册") + InvitationRecord("M****e", "", "未注册"), + InvitationRecord("Q****r", "", "已注册"), + InvitationRecord("W****e", "", "未注册"), + InvitationRecord("E****e", "", "未注册"), + InvitationRecord("R****o", "", "已注册") ) ) recordadapter.notifyDataSetChanged() + } + + // 分享资源图片到微信 + private fun shareImageToWechat() { + try { + // 获取资源图片的URI + val imageUri = Uri.parse("android.resource://${packageName}/${R.drawable.location}") + + val intent = Intent().apply { + action = Intent.ACTION_SEND + type = "image/*" + putExtra(Intent.EXTRA_STREAM, imageUri) + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + setPackage("com.tencent.mm") // 指定微信包名 + } + + // 创建选择器,即使微信不可用也能选择其他应用 + val chooserIntent = Intent.createChooser(intent, "分享邀请图片") + + // 检查是否有应用能处理这个Intent + if (intent.resolveActivity(packageManager) != null) { + startActivity(chooserIntent) + } else { + Toast.makeText(this, "未找到可分享的应用", Toast.LENGTH_SHORT).show() + } + } catch (e: Exception) { + Toast.makeText(this, "分享失败: ${e.message}", Toast.LENGTH_SHORT).show() + } + } + + private fun formatInvitationCode(code: String): String { + return if (code.length > 2) { + code.chunked(2).joinToString(" ") + } else { + code + } } private val scrollRunnable = object : Runnable { @@ -301,6 +364,7 @@ private fun pxToDp(px: Int, context: Context): Int { return (px / (context.resources.displayMetrics.density)).toInt() } + private fun dpToPx(dp: Float): Int { return (dp * resources.displayMetrics.density).toInt() } diff --git a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt index 92f03e9..1dbc3c0 100644 --- a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt +++ b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt @@ -52,20 +52,21 @@ } } - fun login(phone: String, code: String) { + fun login(phone: String, code: String, invite: String) { viewModelScope.launch { _isLoading.value = true try { val request = SmsLoginRequest( username = phone, smsCode = code, + intevailCode = invite, userType = "customer" ) //HttpServletRequest request这是后端 Spring 框架中的一个特殊参数, //用于获取 HTTP 请求的相关信息(如请求头、Cookie 等),它会由 Spring 框架自动注入,不需要客户端显式传递。 val response = RetrofitClient.apiService.verifyCode(request) if (response.code == "0" && response.data != null) { - saveToken(response.data.value,phone) // 这里获取的是 access_token + saveToken(response.data.value, phone) // 这里获取的是 access_token _loginState.value = true } else { _loginMessage.value = response.msg.ifEmpty { "登录失败" } @@ -87,7 +88,7 @@ } } - private fun saveToken(token: String,phone:String) { + private fun saveToken(token: String, phone: String) { // TODO: 实现token存储逻辑 // 可能还需要存储 refresh_token PreferencesManager.saveToken(token) diff --git a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt index d3ae414..7362c83 100644 --- a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt +++ b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt @@ -311,6 +311,8 @@ currentUserInfo = response.data val userInfo = response.data + // 本地保存我的邀请码 + PreferencesManager.setInviteCode(userInfo.intervialcode); // 设置头像 Glide.with(this) .load(userInfo.cover) diff --git a/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt index b9636a9..932bdd3 100644 --- a/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt +++ b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt @@ -10,6 +10,7 @@ private const val KEY_FIRST_INSTALL = "first_install" private const val LAST_LOGIN_PHONE = "last_login_phone" private const val PREF_LAST_CHECK_TIME_PREFIX = "last_check_time_" + private const val KEY_INVITE = "user_invite" private lateinit var preferences: SharedPreferences @@ -64,4 +65,12 @@ fun setLastCheckTime(categoryId: Int, time: Long) { preferences.edit().putLong(PREF_LAST_CHECK_TIME_PREFIX + categoryId, time).apply() } + + fun getInviteCode(): String { + return preferences.getString(KEY_INVITE, "") ?: "" + } + + fun setInviteCode(invite: String) { + preferences.edit().putString(KEY_INVITE, invite).apply() + } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_invitation_main.xml b/app/src/main/res/layout/activity_invitation_main.xml index e92d712..88a6273 100644 --- a/app/src/main/res/layout/activity_invitation_main.xml +++ b/app/src/main/res/layout/activity_invitation_main.xml @@ -63,7 +63,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" - app:cardCornerRadius="8dp"> + app:cardCornerRadius="18dp"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/invitationsuccessRecyclerView" @@ -75,9 +75,10 @@ <!-- 邀请按钮区域 --> <Button + android:id="@+id/btnInvite" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="26dp" + android:layout_marginBottom="10dp" android:backgroundTint="#FF0000" android:insetTop="0dp" android:insetBottom="0dp" @@ -86,6 +87,47 @@ android:textColor="#FFFFFF" android:textSize="16sp" app:cornerRadius="10dp" /> + + <!-- 邀请码区域 --> + <androidx.cardview.widget.CardView + android:layout_width="match_parent" + android:layout_height="50dp" + android:layout_marginBottom="8dp" + app:cardCornerRadius="8dp" + app:cardPreventCornerOverlap="true" + app:cardElevation="0dp" + app:cardBackgroundColor="#FFFFFF"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:gravity="center_vertical"> + + <TextView + android:id="@+id/invitationCodeText" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="A1B2" + android:textAlignment="center" + android:textColor="#000000" + android:textSize="30sp" /> + + <Button + android:id="@+id/copyButton" + android:layout_width="wrap_content" + android:layout_height="40dp" + android:text="复制邀请码" + android:textColor="#FF0000" + android:backgroundTint="#FFFFFF" + android:textSize="12sp" + android:paddingStart="12dp" + android:paddingEnd="12dp"/> + </LinearLayout> + </androidx.cardview.widget.CardView> <!-- 邀请任务表格区域 --> <androidx.cardview.widget.CardView @@ -178,7 +220,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="6dp" - android:text="免广告特权 (7天)" + android:text="15天会员" android:textAlignment="center" android:textColor="#333333" android:textSize="12sp" /> @@ -208,7 +250,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="6dp" - android:text="7天会员" + android:text="30天会员" android:textAlignment="center" android:textColor="#333333" android:textSize="12sp" /> diff --git a/app/src/main/res/layout/activity_phone_login.xml b/app/src/main/res/layout/activity_phone_login.xml index cfb7880..833feb5 100644 --- a/app/src/main/res/layout/activity_phone_login.xml +++ b/app/src/main/res/layout/activity_phone_login.xml @@ -85,6 +85,30 @@ android:layout_width="match_parent" android:layout_height="1dp" android:background="#EEEEEE" /> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="16dp"> + + <EditText + android:id="@+id/etInvite" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@null" + android:hint="邀请码" + android:inputType="phone" + android:maxLength="11" + android:textSize="16sp" + android:padding="12dp"/> + + + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="#EEEEEE" /> </LinearLayout> <Button -- Gitblit v1.9.3