Selaa lähdekoodia

登录页面开发完成

bjb 2 viikkoa sitten
vanhempi
sitoutus
4177bed041
67 muutettua tiedostoa jossa 473 lisäystä ja 62 poistoa
  1. 8 0
      .idea/deploymentTargetSelector.xml
  2. 7 1
      app/src/main/AndroidManifest.xml
  3. BIN
      app/src/main/ic_launcher-playstore.png
  4. 6 7
      app/src/main/java/com/iscs/bozzys/service/AliPushService.kt
  5. 36 30
      app/src/main/java/com/iscs/bozzys/ui/pages/PageSplash.kt
  6. 24 3
      app/src/main/java/com/iscs/bozzys/ui/pages/home/HomeCompose.kt
  7. 0 1
      app/src/main/java/com/iscs/bozzys/ui/pages/home/MyCompose.kt
  8. 319 0
      app/src/main/java/com/iscs/bozzys/ui/pages/login/PageLogin.kt
  9. 10 6
      app/src/main/java/com/iscs/bozzys/ui/theme/Color.kt
  10. 7 7
      app/src/main/java/com/iscs/bozzys/ui/theme/Theme.kt
  11. 37 0
      app/src/main/java/com/iscs/bozzys/utils/LogUtil.kt
  12. 14 0
      app/src/main/java/com/iscs/bozzys/utils/Storage.kt
  13. 2 3
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  14. 2 3
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  15. BIN
      app/src/main/res/mipmap-hdpi/bluetooth.png
  16. BIN
      app/src/main/res/mipmap-hdpi/code.png
  17. BIN
      app/src/main/res/mipmap-hdpi/fingerprint.png
  18. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.webp
  19. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
  20. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
  21. BIN
      app/src/main/res/mipmap-hdpi/login_tips.png
  22. BIN
      app/src/main/res/mipmap-hdpi/logo.webp
  23. BIN
      app/src/main/res/mipmap-hdpi/phone.png
  24. BIN
      app/src/main/res/mipmap-hdpi/pwd.png
  25. BIN
      app/src/main/res/mipmap-hdpi/qrcode.png
  26. BIN
      app/src/main/res/mipmap-hdpi/user.png
  27. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.webp
  28. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
  29. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
  30. BIN
      app/src/main/res/mipmap-mdpi/logo.webp
  31. BIN
      app/src/main/res/mipmap-xhdpi/bluetooth.png
  32. BIN
      app/src/main/res/mipmap-xhdpi/code.png
  33. BIN
      app/src/main/res/mipmap-xhdpi/fingerprint.png
  34. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.webp
  35. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
  36. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
  37. BIN
      app/src/main/res/mipmap-xhdpi/login_tips.png
  38. BIN
      app/src/main/res/mipmap-xhdpi/logo.webp
  39. BIN
      app/src/main/res/mipmap-xhdpi/phone.png
  40. BIN
      app/src/main/res/mipmap-xhdpi/pwd.png
  41. BIN
      app/src/main/res/mipmap-xhdpi/qrcode.png
  42. BIN
      app/src/main/res/mipmap-xhdpi/user.png
  43. BIN
      app/src/main/res/mipmap-xxhdpi/bluetooth.png
  44. BIN
      app/src/main/res/mipmap-xxhdpi/code.png
  45. BIN
      app/src/main/res/mipmap-xxhdpi/fingerprint.png
  46. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
  47. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
  48. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
  49. BIN
      app/src/main/res/mipmap-xxhdpi/login_tips.png
  50. BIN
      app/src/main/res/mipmap-xxhdpi/logo.webp
  51. BIN
      app/src/main/res/mipmap-xxhdpi/phone.png
  52. BIN
      app/src/main/res/mipmap-xxhdpi/pwd.png
  53. BIN
      app/src/main/res/mipmap-xxhdpi/qrcode.png
  54. BIN
      app/src/main/res/mipmap-xxhdpi/user.png
  55. BIN
      app/src/main/res/mipmap-xxxhdpi/bluetooth.png
  56. BIN
      app/src/main/res/mipmap-xxxhdpi/code.png
  57. BIN
      app/src/main/res/mipmap-xxxhdpi/fingerprint.png
  58. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
  59. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
  60. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
  61. BIN
      app/src/main/res/mipmap-xxxhdpi/login_tips.png
  62. BIN
      app/src/main/res/mipmap-xxxhdpi/logo.webp
  63. BIN
      app/src/main/res/mipmap-xxxhdpi/phone.png
  64. BIN
      app/src/main/res/mipmap-xxxhdpi/pwd.png
  65. BIN
      app/src/main/res/mipmap-xxxhdpi/qrcode.png
  66. BIN
      app/src/main/res/mipmap-xxxhdpi/user.png
  67. 1 1
      app/src/main/res/values/themes.xml

+ 8 - 0
.idea/deploymentTargetSelector.xml

@@ -4,6 +4,14 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
+        <DropdownSelection timestamp="2025-12-09T10:01:36.687097400Z">
+          <Target type="DEFAULT_BOOT">
+            <handle>
+              <DeviceId pluginId="PhysicalDevice" identifier="serial=d8d12db95670c08" />
+            </handle>
+          </Target>
+        </DropdownSelection>
+        <DialogSelection />
       </SelectionState>
     </selectionStates>
   </component>

+ 7 - 1
app/src/main/AndroidManifest.xml

@@ -20,18 +20,24 @@
             android:name=".ui.pages.PageSplash"
             android:exported="true"
             android:label="@string/app_name"
+            android:screenOrientation="portrait"
             android:theme="@style/Theme.BozzysSplash">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <!--  登录页面  -->
+        <activity
+            android:name=".ui.pages.login.PageLogin"
+            android:screenOrientation="portrait"
+            android:exported="true" />
         <!--  主页面  -->
         <activity
             android:name=".ui.pages.home.PageHome"
             android:exported="true"
             android:launchMode="singleTask"
-            android:theme="@style/Theme.Bozzys" />
+            android:screenOrientation="portrait" />
         <!--  阿里消息推送服务配置  -->
         <service
             android:name=".service.AliPushService"

BIN
app/src/main/ic_launcher-playstore.png


+ 6 - 7
app/src/main/java/com/iscs/bozzys/service/AliPushService.kt

@@ -1,30 +1,29 @@
 package com.iscs.bozzys.service
 
 import android.content.Context
-import android.util.Log
 import com.alibaba.sdk.android.push.AliyunMessageIntentService
 import com.alibaba.sdk.android.push.notification.CPushMessage
 
 class AliPushService : AliyunMessageIntentService() {
 
     override fun onNotification(p0: Context?, p1: String?, p2: String?, p3: Map<String?, String?>?) {
-        Log.d("xiaoming","push onNotification")
+
     }
 
     override fun onMessage(p0: Context?, p1: CPushMessage?) {
-        Log.d("xiaoming","push onMessage")
+
     }
 
     override fun onNotificationOpened(p0: Context?, p1: String?, p2: String?, p3: String?) {
-        Log.d("xiaoming","push onNotificationOpened")
+
     }
 
     override fun onNotificationClickedWithNoAction(p0: Context?, p1: String?, p2: String?, p3: String?) {
-        Log.d("xiaoming","push onNotificationClickedWithNoAction")
+
     }
 
     override fun onNotificationRemoved(p0: Context?, p1: String?) {
-        Log.d("xiaoming","push onNotificationRemoved")
+
     }
 
     override fun onNotificationReceivedInApp(
@@ -36,6 +35,6 @@ class AliPushService : AliyunMessageIntentService() {
         p5: String?,
         p6: String?
     ) {
-        Log.d("xiaoming","push onNotificationReceivedInApp")
+
     }
 }

+ 36 - 30
app/src/main/java/com/iscs/bozzys/ui/pages/PageSplash.kt

@@ -3,10 +3,15 @@ package com.iscs.bozzys.ui.pages
 import android.app.NotificationChannel
 import android.app.NotificationManager
 import android.graphics.Color
-import android.util.Log
+import android.os.Build
+import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
 import com.alibaba.sdk.android.push.CloudPushService
 import com.alibaba.sdk.android.push.CommonCallback
 import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory
@@ -14,6 +19,8 @@ import com.iscs.bozzys.R
 import com.iscs.bozzys.service.AliPushService
 import com.iscs.bozzys.ui.base.PageBase
 import com.iscs.bozzys.ui.pages.home.openPageHome
+import com.iscs.bozzys.ui.pages.login.openPageLogin
+import com.iscs.bozzys.utils.Storage
 import kotlinx.coroutines.delay
 
 /**
@@ -24,18 +31,18 @@ class PageSplash : PageBase() {
     @Composable
     override fun GetViews(pv: PaddingValues) {
         // 配置页面显示控件
-//        Image(
-//            painter = painterResource(R.mipmap.ic_launcher_round),
-//            contentDescription = "",
-//            modifier = Modifier.fillMaxSize(),
-//            contentScale = ContentScale.FillBounds
-//        )
+        Image(
+            painter = painterResource(R.mipmap.logo),
+            contentDescription = "",
+            modifier = Modifier.fillMaxSize(),
+            contentScale = ContentScale.FillWidth
+        )
         // 协程处理跳转事件
         LaunchedEffect(Unit) {
             // 做SDK的初始化操作,有一些没必要在Application中初始化操作的,在这里进行初始化操作
             initSDK()
             delay(3000)
-            openPageHome()
+            if (Storage.isLogin()) openPageHome() else openPageLogin()
             destroyDelay(1000)
         }
     }
@@ -62,38 +69,37 @@ class PageSplash : PageBase() {
 
             override fun onSuccess(msg: String?) {
                 // 消息推送初始化成功
-                Log.d("xiaoming", "Push init success, deviceId is ${PushServiceFactory.getCloudPushService().deviceId}")
                 // 这里可能要告知服务端当前推送的设备id,便于后续设备推送通知
             }
 
             override fun onFailed(errCode: String?, errMsg: String?) {
                 // 消息推送初始化失败
-                Log.d("xiaoming", "Push init failed code $errCode msg $errMsg")
             }
 
         })
 
         // 建立通知通道
-        val nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
-        // 通知渠道的id。这个id值需要给后端开发和运维人员,推送的时候对应 AndroidNotificationChannel 参数。
-        val channelId = "normal"
-        // 用户可以看到的通知渠道的描述。
-        val description = getString(R.string.push_channel_normal)
-        val importance = NotificationManager.IMPORTANCE_HIGH
-        val channel = NotificationChannel(channelId, description, importance)
-
-        // 配置通知渠道的属性。
-        channel.description = description
-        // 设置通知出现时的闪灯(如果Android设备支持的话)。
-        channel.enableLights(true)
-        channel.lightColor = Color.RED
-        // 设置通知出现时的震动(如果Android设备支持的话)。
-        channel.enableVibration(true)
-        // 自定义铃声
-        // channel.setSound(Uri.parse("android.resource://${packageName}/${R.raw.push_hongbao}"), Notification.AUDIO_ATTRIBUTES_DEFAULT)
-        channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
-        // 最后在NotificationManager中创建该通知渠道。
-        nm.createNotificationChannel(channel)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            val nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+            // 通知渠道的id。这个id值需要给后端开发和运维人员,推送的时候对应 AndroidNotificationChannel 参数。
+            val channelId = "normal"
+            // 用户可以看到的通知渠道的描述。
+            val description = getString(R.string.push_channel_normal)
+            val importance = NotificationManager.IMPORTANCE_HIGH
+            val channel = NotificationChannel(channelId, description, importance)
+            // 配置通知渠道的属性。
+            channel.description = description
+            // 设置通知出现时的闪灯(如果Android设备支持的话)。
+            channel.enableLights(true)
+            channel.lightColor = Color.RED
+            // 设置通知出现时的震动(如果Android设备支持的话)。
+            channel.enableVibration(true)
+            // 自定义铃声
+            // channel.setSound(Uri.parse("android.resource://${packageName}/${R.raw.push_hongbao}"), Notification.AUDIO_ATTRIBUTES_DEFAULT)
+            channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
+            // 最后在NotificationManager中创建该通知渠道。
+            nm.createNotificationChannel(channel)
+        }
     }
 
 }

+ 24 - 3
app/src/main/java/com/iscs/bozzys/ui/pages/home/HomeCompose.kt

@@ -1,23 +1,44 @@
 package com.iscs.bozzys.ui.pages.home
 
 import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.Text
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
 import androidx.compose.ui.zIndex
+import com.iscs.bozzys.ui.theme.Main
 
 @Composable
 fun HomeCompose(pv: PaddingValues, zIndex: Float) {
-    Column(
+    Box(
         modifier = Modifier
             .fillMaxSize()
             .zIndex(zIndex)
             .background(Color(0xFFF8F8F8))
     ) {
-        Text("首页")
+        // 顶部工具栏
+        Column(
+            modifier = Modifier
+                .fillMaxWidth()
+                .background(Main)
+                .padding(top = pv.calculateTopPadding())
+        ) {
+            Row(
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .height(66.dp)
+
+            ) {
+
+            }
+        }
     }
 }

+ 0 - 1
app/src/main/java/com/iscs/bozzys/ui/pages/home/MyCompose.kt

@@ -23,6 +23,5 @@ fun MyCompose(pv: PaddingValues, zIndex: Float) {
         Text("我的")
     }
     LaunchedEffect("") {
-        Log.d("xiaoming", "我的")
     }
 }

+ 319 - 0
app/src/main/java/com/iscs/bozzys/ui/pages/login/PageLogin.kt

@@ -0,0 +1,319 @@
+package com.iscs.bozzys.ui.pages.login
+
+import android.content.Context
+import android.content.Intent
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalTextStyle
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.platform.LocalSoftwareKeyboardController
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.VisualTransformation
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.iscs.bozzys.R
+import com.iscs.bozzys.ui.base.PageBase
+import com.iscs.bozzys.ui.theme.Main
+import com.iscs.bozzys.ui.theme.SubMain
+import com.iscs.bozzys.ui.theme.Text
+import com.iscs.bozzys.ui.theme.TextDesc
+
+/**
+ * 打开登录页面
+ */
+fun Context.openPageLogin() {
+    startActivity(Intent(this, PageLogin::class.java))
+}
+
+/**
+ * 登录页面
+ */
+class PageLogin : PageBase() {
+
+    @Composable
+    override fun GetViews(pv: PaddingValues) {
+        val keyboard = LocalSoftwareKeyboardController.current
+        Column(
+            Modifier
+                .fillMaxSize()
+                .background(Color.White)
+                .clickable(onClick = { keyboard?.hide() }, indication = null, interactionSource = remember { MutableInteractionSource() })
+        ) {
+            // 顶部显示模块
+            Column(
+                Modifier
+                    .fillMaxWidth()
+                    .weight(1f)
+                    .background(Main),
+                horizontalAlignment = Alignment.CenterHorizontally
+            ) {
+                Spacer(
+                    Modifier
+                        .fillMaxWidth()
+                        .weight(3f)
+                )
+                Text("博士安全能量隔离系统", fontSize = 24.sp, color = Text)
+                Spacer(
+                    Modifier
+                        .fillMaxWidth()
+                        .height(8.dp)
+                )
+                Text("温州博士安全科技有限公司", fontSize = 14.sp, color = TextDesc)
+                Spacer(
+                    Modifier
+                        .fillMaxWidth()
+                        .weight(1f)
+                )
+            }
+            Box(
+                Modifier
+                    .fillMaxSize()
+                    .weight(4f)
+            ) {
+                // 登录输入框布局
+                LoginCompose()
+            }
+        }
+    }
+
+    @Composable
+    fun LoginCompose() {
+        // 当前登录方式
+        // 0 - 验证码 1 - 账号密码
+        val loginType = remember { mutableStateOf(0) }
+        // 账号
+        val account = remember { mutableStateOf("") }
+        // 验证码或密码
+        val code = remember { mutableStateOf("") }
+        Column(
+            Modifier
+                .fillMaxSize()
+                .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally
+        ) {
+            Text("欢迎登录", fontSize = 20.sp, fontWeight = FontWeight.SemiBold, color = Text, modifier = Modifier.padding(top = 30.dp))
+            Row(
+                Modifier
+                    .padding(top = 24.dp)
+                    .size(335.dp, 47.dp)
+                    .border(1.dp, color = Color(0xFFD1D5DB), shape = RoundedCornerShape(12.dp))
+                    .clip(RoundedCornerShape(12.dp)),
+                verticalAlignment = Alignment.CenterVertically
+            ) {
+                Text(
+                    "短信登录",
+                    Modifier
+                        .weight(1f)
+                        .fillMaxHeight()
+                        .background(if (loginType.value == 0) SubMain else Color.White)
+                        .clickable(onClick = { loginType.value = 0 }),
+                    color = if (loginType.value == 0) Main else TextDesc,
+                    lineHeight = 47.sp,
+                    fontSize = 14.sp,
+                    fontWeight = if (loginType.value == 0) FontWeight.SemiBold else FontWeight.Normal,
+                    textAlign = TextAlign.Center
+                )
+                Text(
+                    "密码登录",
+                    Modifier
+                        .weight(1f)
+                        .fillMaxHeight()
+                        .background(if (loginType.value == 1) SubMain else Color.White)
+                        .clickable(onClick = { loginType.value = 1 }),
+                    color = if (loginType.value == 1) Main else TextDesc,
+                    lineHeight = 47.sp,
+                    fontSize = 14.sp,
+                    fontWeight = if (loginType.value == 1) FontWeight.SemiBold else FontWeight.Normal,
+                    textAlign = TextAlign.Center,
+                )
+            }
+            Row(
+                Modifier
+                    .padding(top = 24.dp)
+                    .size(335.dp, 50.dp)
+                    .border(1.dp, color = Color(0xFFD1D5DB), shape = RoundedCornerShape(5.dp))
+                    .padding(horizontal = 12.dp),
+                verticalAlignment = Alignment.CenterVertically
+            ) {
+                val resId = if (loginType.value == 0) R.mipmap.phone else R.mipmap.user
+                Icon(painter = painterResource(resId), contentDescription = null, tint = Color(0xFF999999))
+                BasicTextField(
+                    account.value,
+                    onValueChange = { value ->
+                        account.value = if (loginType.value == 0) {
+                            // 手机号只能输入数字,不能包含小数点
+                            value.filter(Char::isDigit)
+                        } else {
+                            value
+                        }
+                    },
+                    Modifier
+                        .padding(horizontal = 16.dp)
+                        .weight(1f),
+                    singleLine = true,
+                    textStyle = LocalTextStyle.current.copy(fontSize = 16.sp, lineHeight = 20.sp),
+                    decorationBox = { innerTextField ->
+                        Box(contentAlignment = Alignment.CenterStart) {
+                            innerTextField()
+                            if (account.value.isEmpty()) {
+                                val text = if (loginType.value == 0) "请输入手机号" else "请输入用户名"
+                                Text(text, color = Color(0xFF9CA3AF), fontSize = 16.sp, lineHeight = 20.sp)
+                            }
+                        }
+                    },
+                    cursorBrush = SolidColor(Main),
+                    keyboardOptions = KeyboardOptions(keyboardType = if (loginType.value == 0) KeyboardType.Number else KeyboardType.Email)
+                )
+            }
+            Row(
+                Modifier
+                    .padding(top = 20.dp)
+                    .size(335.dp, 50.dp)
+                    .border(1.dp, color = Color(0xFFD1D5DB), shape = RoundedCornerShape(5.dp))
+                    .padding(horizontal = 12.dp),
+                verticalAlignment = Alignment.CenterVertically
+            ) {
+                val resId = if (loginType.value == 0) R.mipmap.code else R.mipmap.pwd
+                Icon(painter = painterResource(resId), contentDescription = null, tint = Color(0xFF999999))
+                BasicTextField(
+                    code.value,
+                    onValueChange = { value ->
+                        code.value = if (loginType.value == 0) {
+                            // 验证码只能输入数字,不能包含小数点
+                            value.filter(Char::isDigit)
+                        } else {
+                            value
+                        }
+                    },
+                    Modifier
+                        .padding(horizontal = 16.dp)
+                        .weight(1f),
+                    singleLine = true,
+                    textStyle = LocalTextStyle.current.copy(fontSize = 16.sp, lineHeight = 20.sp),
+                    decorationBox = { innerTextField ->
+                        Box(contentAlignment = Alignment.CenterStart) {
+                            innerTextField()
+                            if (code.value.isEmpty()) {
+                                val text = if (loginType.value == 0) "请输入验证码" else "请输入密码"
+                                Text(text, color = Color(0xFF9CA3AF), fontSize = 16.sp, lineHeight = 20.sp)
+                            }
+                        }
+                    },
+                    cursorBrush = SolidColor(Main),
+                    visualTransformation = if (loginType.value == 0) VisualTransformation.None else PasswordVisualTransformation(),
+                    keyboardOptions = KeyboardOptions(keyboardType = if (loginType.value == 0) KeyboardType.Number else KeyboardType.Password)
+                )
+            }
+            // 登录按钮
+            Button(
+                onClick = {}, Modifier
+                    .padding(top = 30.dp)
+                    .size(335.dp, 52.dp)
+                    .clip(RoundedCornerShape(5.dp))
+                    .background(Main)
+            ) {
+                Text("登 录", fontSize = 16.sp)
+            }
+            // 账号提示
+            Row(Modifier.padding(top = 16.dp), verticalAlignment = Alignment.CenterVertically) {
+                Icon(painter = painterResource(R.mipmap.login_tips), contentDescription = null, tint = Color(0xFF6B7280))
+                Text("工业安全系统,请妥善保管账号信息", Modifier.padding(start = 5.dp), fontSize = 12.sp, color = Color(0xFF6B7280))
+            }
+            // 其他登录方式
+            Box(Modifier.padding(top = 20.dp), contentAlignment = Alignment.Center) {
+                Spacer(
+                    Modifier
+                        .size(335.dp, 1.dp)
+                        .background(Color(0xFFEEEEEE))
+                )
+                Text(
+                    "其他登录方式", Modifier
+                        .background(Color.White)
+                        .padding(horizontal = 5.dp),
+                    fontSize = 14.sp, color = Color(0xFF999999)
+                )
+            }
+            Row(Modifier.padding(top = 30.dp, bottom = 10.dp), verticalAlignment = Alignment.CenterVertically) {
+                Icon(
+                    painter = painterResource(R.mipmap.fingerprint),
+                    contentDescription = null,
+                    Modifier
+                        .padding(horizontal = 10.dp)
+                        .size(50.dp)
+                        .clip(RoundedCornerShape(50))
+                        .background(Color(0xFFF5F5F5))
+                        .padding(15.dp),
+                    tint = Color(0xFF6B7280)
+                )
+                Icon(
+                    painter = painterResource(R.mipmap.qrcode),
+                    contentDescription = null,
+                    Modifier
+                        .padding(horizontal = 10.dp)
+                        .size(50.dp)
+                        .clip(RoundedCornerShape(50))
+                        .background(Color(0xFFF5F5F5))
+                        .padding(15.dp),
+                    tint = Color(0xFF6B7280)
+                )
+                Icon(
+                    painter = painterResource(R.mipmap.bluetooth),
+                    contentDescription = null,
+                    Modifier
+                        .padding(horizontal = 10.dp)
+                        .size(50.dp)
+                        .clip(RoundedCornerShape(50))
+                        .background(Color(0xFFF5F5F5))
+                        .padding(15.dp),
+                    tint = Color(0xFF6B7280)
+                )
+            }
+            Spacer(Modifier.weight(2f))
+            // 底部版本等提示
+            Column(Modifier.width(335.dp), horizontalAlignment = Alignment.CenterHorizontally) {
+                Spacer(
+                    Modifier
+                        .fillMaxWidth()
+                        .height(1.dp)
+                        .background(Color(0xFFEEEEEE))
+                )
+                Text("LOTO智能锁控·能量安全隔离", Modifier.padding(top = 20.dp, bottom = 4.dp), fontSize = 14.sp, color = Color(0xFF666666))
+                Text("版本 v1.0.0", Modifier.padding(bottom = 20.dp), fontSize = 14.sp, color = Color(0xFF666666))
+            }
+            Spacer(Modifier.weight(1f))
+        }
+    }
+
+}

+ 10 - 6
app/src/main/java/com/iscs/bozzys/ui/theme/Color.kt

@@ -2,10 +2,14 @@ package com.iscs.bozzys.ui.theme
 
 import androidx.compose.ui.graphics.Color
 
-val Purple80 = Color(0xFFD0BCFF)
-val PurpleGrey80 = Color(0xFFCCC2DC)
-val Pink80 = Color(0xFFEFB8C8)
+// 默认主题色
+val Main = Color(0xFFFFA500)
 
-val Purple40 = Color(0xFF6650a4)
-val PurpleGrey40 = Color(0xFF625b71)
-val Pink40 = Color(0xFF7D5260)
+// 子主题色
+val SubMain = Color(0xFFFFEDD5)
+
+// 默认字体颜色
+val Text = Color(0xFF333333)
+
+// 描述字体颜色
+val TextDesc = Color(0xFF4B5563)

+ 7 - 7
app/src/main/java/com/iscs/bozzys/ui/theme/Theme.kt

@@ -12,23 +12,23 @@ import androidx.compose.ui.platform.LocalContext
 
 // 暗黑主题配置
 private val DarkColorScheme = darkColorScheme(
-    primary = Purple80,
-    secondary = PurpleGrey80,
-    tertiary = Pink80
+    primary = Main,
+    secondary = Main,
+    tertiary = Main
 )
 
 // 标准主题配置
 private val LightColorScheme = lightColorScheme(
-    primary = Purple40,
-    secondary = PurpleGrey40,
-    tertiary = Pink40
+    primary = Main,
+    secondary = Main,
+    tertiary = Main
 )
 
 @Composable
 fun BozzysTheme(
     darkTheme: Boolean = isSystemInDarkTheme(),
     // Dynamic color is available on Android 12+
-    dynamicColor: Boolean = true, // 这个会影响部分机器不会变化
+    dynamicColor: Boolean = false, // 这个会影响部分机器不会变化 默认修改为false
     content: @Composable () -> Unit
 ) {
     val colorScheme = when {

+ 37 - 0
app/src/main/java/com/iscs/bozzys/utils/LogUtil.kt

@@ -0,0 +1,37 @@
+package com.iscs.bozzys.utils
+
+import android.util.Log
+
+object LogUtil {
+
+    var showLog = true
+
+    /**
+     * INFO级别日志输出
+     */
+    fun i(tag: String, msg: String) {
+        if (showLog) Log.i("Bozzys $tag", msg)
+    }
+
+    /**
+     * DEBUG级别日志输出
+     */
+    fun d(tag: String, msg: String) {
+        if (showLog) Log.d("Bozzys $tag", msg)
+    }
+
+    /**
+     * WARNING级别日志输出
+     */
+    fun w(tag: String, msg: String) {
+        if (showLog) Log.w("Bozzys $tag", msg)
+    }
+
+    /**
+     * ERROR级别日志输出
+     */
+    fun e(tag: String, msg: String) {
+        if (showLog) Log.e("Bozzys $tag", msg)
+    }
+
+}

+ 14 - 0
app/src/main/java/com/iscs/bozzys/utils/Storage.kt

@@ -18,6 +18,20 @@ object Storage {
         mmkv = MMKV.defaultMMKV()
     }
 
+    /**
+     * 保存当前登录状态
+     */
+    fun saveLogin(isLogin: Boolean) {
+        mmkv.encode("is_login", isLogin)
+    }
+
+    /**
+     * 是否已经登录
+     */
+    fun isLogin(): Boolean {
+        return mmkv.decodeBool("is_login", false)
+    }
+
     /**
      * 存储token
      */

+ 2 - 3
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@drawable/ic_launcher_background" />
-    <foreground android:drawable="@drawable/ic_launcher_foreground" />
-    <monochrome android:drawable="@drawable/ic_launcher_foreground" />
+    <background android:drawable="@color/white"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
 </adaptive-icon>

+ 2 - 3
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@drawable/ic_launcher_background" />
-    <foreground android:drawable="@drawable/ic_launcher_foreground" />
-    <monochrome android:drawable="@drawable/ic_launcher_foreground" />
+    <background android:drawable="@color/white"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
 </adaptive-icon>

BIN
app/src/main/res/mipmap-hdpi/bluetooth.png


BIN
app/src/main/res/mipmap-hdpi/code.png


BIN
app/src/main/res/mipmap-hdpi/fingerprint.png


BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp


BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp


BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp


BIN
app/src/main/res/mipmap-hdpi/login_tips.png


BIN
app/src/main/res/mipmap-hdpi/logo.webp


BIN
app/src/main/res/mipmap-hdpi/phone.png


BIN
app/src/main/res/mipmap-hdpi/pwd.png


BIN
app/src/main/res/mipmap-hdpi/qrcode.png


BIN
app/src/main/res/mipmap-hdpi/user.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp


BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp


BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp


BIN
app/src/main/res/mipmap-mdpi/logo.webp


BIN
app/src/main/res/mipmap-xhdpi/bluetooth.png


BIN
app/src/main/res/mipmap-xhdpi/code.png


BIN
app/src/main/res/mipmap-xhdpi/fingerprint.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp


BIN
app/src/main/res/mipmap-xhdpi/login_tips.png


BIN
app/src/main/res/mipmap-xhdpi/logo.webp


BIN
app/src/main/res/mipmap-xhdpi/phone.png


BIN
app/src/main/res/mipmap-xhdpi/pwd.png


BIN
app/src/main/res/mipmap-xhdpi/qrcode.png


BIN
app/src/main/res/mipmap-xhdpi/user.png


BIN
app/src/main/res/mipmap-xxhdpi/bluetooth.png


BIN
app/src/main/res/mipmap-xxhdpi/code.png


BIN
app/src/main/res/mipmap-xxhdpi/fingerprint.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp


BIN
app/src/main/res/mipmap-xxhdpi/login_tips.png


BIN
app/src/main/res/mipmap-xxhdpi/logo.webp


BIN
app/src/main/res/mipmap-xxhdpi/phone.png


BIN
app/src/main/res/mipmap-xxhdpi/pwd.png


BIN
app/src/main/res/mipmap-xxhdpi/qrcode.png


BIN
app/src/main/res/mipmap-xxhdpi/user.png


BIN
app/src/main/res/mipmap-xxxhdpi/bluetooth.png


BIN
app/src/main/res/mipmap-xxxhdpi/code.png


BIN
app/src/main/res/mipmap-xxxhdpi/fingerprint.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp


BIN
app/src/main/res/mipmap-xxxhdpi/login_tips.png


BIN
app/src/main/res/mipmap-xxxhdpi/logo.webp


BIN
app/src/main/res/mipmap-xxxhdpi/phone.png


BIN
app/src/main/res/mipmap-xxxhdpi/pwd.png


BIN
app/src/main/res/mipmap-xxxhdpi/qrcode.png


BIN
app/src/main/res/mipmap-xxxhdpi/user.png


+ 1 - 1
app/src/main/res/values/themes.xml

@@ -8,7 +8,7 @@
         <item name="android:windowTranslucentNavigation">true</item>
         <item name="android:statusBarColor">@android:color/transparent</item>
         <item name="android:windowFullscreen">true</item>
-        <item name="android:background">@mipmap/ic_launcher</item>
+        <item name="android:background">@color/white</item>
     </style>
 
 </resources>