task(0a00ccbd-6f98-4730-adf2-6f1e864823de): Mount M2 project workbench home and modernize M1 layouts

- FeatureMount: HOME tab now mounts ProjectWorkspaceFragment; delete placeholder HomeFragment
- app/build.gradle.kts + libs.versions.toml: add androidx recyclerview and swiperefreshlayout for project list and pull-to-refresh
- NetworkModule: register ProjectApi (M2 2.5.1.1 GetProjectList) via provideProjectApi
- SessionRepository: add SessionState.Restoring as initial state so cold start renders neutral loading instead of prompting login
- MineFragment/layout: consumer-grade flow with horizontal identity card (whole card acts as login CTA when signed out), config warning card, grouped settings rows; drop back button and manual refresh entry
- MineViewModel: remove manual refresh(); session restore is now automatic on cold start
- LoginFragment/layout: MaterialToolbar back, segmented MaterialButtonToggleGroup for account/SMS mode, TextInputLayout floating-label inputs, linear progress below button
- ConfigFragment/ChangePasswordFragment layouts: unify back navigation to Toolbar, switch plain EditTexts to TextInputLayout, replace ProgressBar with LinearProgressIndicator
- strings.xml: add M2 home workbench copy and mine/login labels; remove unused action_back, mine_login, mine_refresh, mine_config_ready, mine_logout_confirm
This commit is contained in:
阿猫
2026-09-03 23:50:20 +08:00
parent dec274b1af
commit ddd5009bb1
29 changed files with 1668 additions and 431 deletions

View File

@@ -1,6 +1,7 @@
package com.stec.cmd.core.network
import com.stec.cmd.core.network.api.AuthApi
import com.stec.cmd.core.network.api.ProjectApi
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -72,6 +73,11 @@ object NetworkModule {
@Singleton
fun provideAuthApi(retrofit: Retrofit): AuthApi = retrofit.create(AuthApi::class.java)
/** 项目接口M22.5.1.1)。 */
@Provides
@Singleton
fun provideProjectApi(retrofit: Retrofit): ProjectApi = retrofit.create(ProjectApi::class.java)
/** 仅满足 Retrofit 构造约束;真实地址请求期经 DynamicBaseUrlInterceptor 改写。 */
private const val PLACEHOLDER_BASE_URL = "https://placeholder.stec.invalid/"

View File

@@ -0,0 +1,37 @@
package com.stec.cmd.core.network.api
import com.stec.cmd.core.network.ApiEnvelope
import kotlinx.serialization.json.JsonElement
import retrofit2.http.GET
import retrofit2.http.Query
/**
* 项目接口(接口管理规范 V4.5 · 测试环境 https://jcd.stec.p-q.co
* - 2.5.1.1 获取当前用户项目列表M2-01/02/03
*
* 三要素请求头SecretKey/SystemCode/Token由 AuthInterceptor 统一注入。
* 服务端仅返回当前用户有权限的、项目阶段为「进行中」的项目。
*
* 契约宽容:文档约定 data 为 {"ProjectList":[…]};与登录接口(任务 ca3394be
* 同理保留形态偏差可能,故以 [JsonElement] 宽容承载,
* 由 app 层 ProjectRepository.projectListFromData 归一提取。
*/
interface ProjectApi {
/**
* 2.5.1.1 当前用户项目列表:[projectId] 传 null 时 Retrofit 省略参数,
* 返回全部有权限项目;传值时仅返回该 ID 的单条列表数据。
*/
@GET(PATH_GET_PROJECT_LIST)
suspend fun getProjectList(
@Query(QUERY_PROJECT_ID) projectId: String? = null,
): ApiEnvelope<JsonElement>
companion object {
// ---- 接口管理规范 V4.5 · 章节 2.1 所有 API 目录 ----
const val PATH_GET_PROJECT_LIST = "OutWebApi/api/GetProjectList"
/** 2.5.1.1 查询参数名(非必填,空则返回全部)。 */
const val QUERY_PROJECT_ID = "ProjectID"
}
}

View File

@@ -0,0 +1,23 @@
package com.stec.cmd.core.network.api
import kotlinx.serialization.Serializable
/**
* 项目 DTO接口管理规范 V4.5 · 2.5.1.1 / 2.5.1.6)。
*
* 字段名与平台契约一致PascalCase文档未给类型全 `String?` 容错,
* 响应侧配合 Json.ignoreUnknownKeys 容忍字段演进。
*/
@Serializable
data class ProjectItem(
/** 项目 ID。 */
val ID: String? = null,
/** 项目编号。 */
val ProjectCode: String? = null,
/** 项目简称。 */
val SimpleName: String? = null,
/** 项目等级:总院重点 | 部门重点 | 一般项目。 */
val ProjectScale: String? = null,
/** 项目阶段:未开始 | 进行中 | 已结束2.5.1.1 服务端仅返回「进行中」)。 */
val ProjectPhase: String? = null,
)