Files
DadaoTask/android/app/build.gradle.kts
T
dadao 17be9d1d42
CI / backend (push) Canceled after 0s
feat(rich): 安卓能编辑富文本了,图片直链换成短期签名,表格不再撑破抽屉
三件欠账一次清:

1. 图片直链签名化
   - 新增 `backend/app/services/signing.py`:HMAC-SHA256,密钥由 `JWT_SECRET` 域分离派生
     (`attachment-raw-v1`),载荷 `workspace_id:attachment_id:exp`,默认 30 分钟
   - `/raw` 支持 `?exp=&sig=`,不需要登录态;签名里绑了工作区,跨租户链接直接拒
   - 附件对象多一个 `raw_url`,前端每次渲染现签,正文里只存不带凭据的 `/raw`
   - 保留旧 `?token=` 通道,给未升级的客户端过渡

2. 安卓富文本编辑器
   - `ui/RichTextEditorScreen.kt`:Markdown 工具栏(粗体/斜体/标题/列表/引用/代码/链接/图片),
     选区包裹与行首前缀都按光标位置来;贴图走附件接口,插入签名直链
   - 预览用 Markwon,图片用 Coil;正文落在一张白纸卡片里,不再贴屏幕边
   - 从任务详情与知识点都能进,保存按 `body_md` 回写(PATCH 带 version)

3. 表格
   - 只读渲染走 markdown-it 的 GFM 表,`display:block + overflow-x:auto`:
     宽表横向滚动、窄表铺满,都不撑破抽屉

验证:pytest 74 passed;richtext 15 / smoke 7 / tickets 8 / knowledge 7 全绿;
tsc -b 0 错;vite build 通过(主包 299.42 kB / gzip 74.96 kB);
安卓 assembleDebug 成功并在 API 35 模拟器走通编辑与预览。

仍欠:保存后回列表而非回详情抽屉、图片压缩与缩略图、HTML 片段按文本显示。
2026-10-29 03:32:53 +08:00

81 lines
2.6 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
id("org.jetbrains.kotlin.plugin.serialization")
}
/**
* 后端地址不走硬编码:优先读 local.properties 的 dadao.apiBase,
* 缺省指向模拟器访问宿主机的 10.0.2.2:8100。
*/
val apiBase: String = run {
val props = Properties()
val file = rootProject.file("local.properties")
if (file.exists()) file.inputStream().use { props.load(it) }
props.getProperty("dadao.apiBase") ?: "http://10.0.2.2:8100"
}
android {
namespace = "com.dadao.task"
compileSdk = 35
defaultConfig {
applicationId = "com.dadao.task"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "0.1.0"
buildConfigField("String", "API_BASE", "\"$apiBase\"")
}
buildFeatures {
compose = true
buildConfig = true
}
/**
* 调试签名用仓库内的 keystore,而不是 ~/.android/debug.keystore。
*
* 原因:CI 与受限沙箱里 `~/.android` 常常不可写,AGP 会去建
* `debug.keystore.lock` 然后 AccessDenied,构建在 validateSigningDebug 这一步失败。
* 放在工程里就能在任何机器上直接 assembleDebug。
* 注意:这只是调试签名,release 必须换成真正的证书并走 secret 注入。
*/
signingConfigs {
getByName("debug") {
storeFile = rootProject.file("keystore/debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.12.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.activity:activity-compose:1.9.3")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.7")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Markdown 预览用成熟库渲染,不自己写解析器
implementation("io.noties.markwon:core:4.6.2")
implementation("io.coil-kt:coil-compose:2.7.0")
debugImplementation("androidx.compose.ui:ui-tooling")
}