DriftLedger/plugins/sms-receiver/app.plugin.js
fengmengqi f6437b83fe feat: 初始化完整应用框架
- 切换到 expo-router 文件路由,删除 App.tsx
- 新增 5 个 Expo 原生插件:ppocr (OCR), accessibility (账单抓取),
  notification-listener, screenshot-monitor, sms-receiver
- 实现核心领域逻辑:billPipeline (账单流水), dedup (去重),
  transferRecognizer (转账识别), ruleEngine + categories (双轨制分类),
  budgets, creditCards, recurring, sync, ocrProcessor
- 增强 ledger.ts:支持 balance assertion, option, pad/note 指令,
  posting 级 metadata, cost/price 解析
- 新增完整 UI:tabs (首页/报表/设置), 交易详情, 预算, 日历热力图,
  分类管理, 信用卡, 定期交易, 规则管理
- 实现 Zustand 状态管理:ledgerStore, importStore, settingsStore,
  metadataStore, automationStore + 持久化
- 新增 AI 功能:chatAssistant, monthlySummary, voiceInput
- 实现多端同步:gitSync, webdavSync, icloudSync
- 新增主题系统 (tokens/presets) 和 i18n (zh/en)
- 添加 30+ 单元测试覆盖核心逻辑
2026-07-15 10:01:31 +08:00

81 lines
2.5 KiB
JavaScript
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.

/**
* 短信监听 Config Pluginplan.md「4.2 短信监听服务」+「决策 4」
*
* 在 expo prebuild 时注册 Android SmsReceivermanifest receiver + RECEIVE_SMS 权限)。
*
* 注意withAndroidManifest 的 modResults 结构是 { manifest: { ... } }
* 操作权限/application 必须通过 modResults.manifest不是 modResults 本身。
*/
const { withAndroidManifest, withDangerousMod } = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');
function withSmsReceiver(config) {
// 1. 复制 Kotlin 源码到原生工程
config = withDangerousMod(config, [
'android',
async (modConfig) => {
const projectRoot = modConfig.modRequest.platformProjectRoot;
const dest = path.join(projectRoot, 'app/src/main/java/com/beancount/mobile/sms');
fs.mkdirSync(dest, { recursive: true });
const srcDir = path.join(__dirname, 'android');
for (const f of fs.readdirSync(srcDir)) {
if (f.endsWith('.kt')) {
fs.copyFileSync(path.join(srcDir, f), path.join(dest, f));
}
}
return modConfig;
},
]);
// 2. 注册 receiver + 权限到 AndroidManifest
config = withAndroidManifest(config, (modConfig) => {
const manifest = modConfig.modResults.manifest;
// 1. 添加 RECEIVE_SMS 权限
if (!manifest['uses-permission']) {
manifest['uses-permission'] = [];
}
const perms = ['android.permission.RECEIVE_SMS'];
for (const perm of perms) {
const exists = manifest['uses-permission'].some(p => p.$['android:name'] === perm);
if (!exists) {
manifest['uses-permission'].push({ $: { 'android:name': perm } });
}
}
// 2. 添加短信 Receiver
const receiverNode = {
$: {
'android:name': 'com.beancount.mobile.sms.BillingSmsReceiver',
'android:exported': 'true',
},
'intent-filter': [{
action: [{ $: { 'android:name': 'android.provider.Telephony.SMS_RECEIVED' } }],
}],
};
// 确保 application[0] 存在
if (!Array.isArray(manifest.application) || manifest.application.length === 0) {
manifest.application = [{ $: {} }];
}
const app = manifest.application[0];
if (!app.receiver) {
app.receiver = [];
}
const exists = app.receiver.some(
r => r.$['android:name'] === 'com.beancount.mobile.sms.BillingSmsReceiver'
);
if (!exists) {
app.receiver.push(receiverNode);
}
return modConfig;
});
return config;
}
module.exports = withSmsReceiver;