diff --git a/Repository/TransactionRecordRepository.cs b/Repository/TransactionRecordRepository.cs index bc87c08..d7c1237 100644 --- a/Repository/TransactionRecordRepository.cs +++ b/Repository/TransactionRecordRepository.cs @@ -661,6 +661,15 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository() + .Where(t => t.Id == currentId) + .FirstAsync(); + + if (currentRecord == null) + { + return new List(); + } + var list = await FreeSql.Select() .Where(t => t.Id != currentId) .Where(t => t.Type != currentType) @@ -668,7 +677,9 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository Math.Abs(Math.Abs(t.Amount) - absAmount)).ToList(); + return list.OrderBy(t => Math.Abs(Math.Abs(t.Amount) - absAmount)) + .ThenBy(x=> Math.Abs((x.OccurredAt - currentRecord.OccurredAt).TotalSeconds)) + .ToList(); } public async Task UpdateCategoryNameAsync(string oldName, string newName, TransactionType type) diff --git a/Service/SmartHandleService.cs b/Service/SmartHandleService.cs index b1e6acd..5c60a43 100644 --- a/Service/SmartHandleService.cs +++ b/Service/SmartHandleService.cs @@ -24,6 +24,10 @@ public class SmartHandleService( // 获取指定ID的账单(作为样本) var sampleRecords = await transactionRepository.GetByIdsAsync(transactionIds); + sampleRecords = sampleRecords + .Where(x => string.IsNullOrEmpty(x.Classify)) + .ToArray(); + if (sampleRecords.Length == 0) { // await WriteEventAsync("error", "找不到指定的账单"); diff --git a/Web/PWA-README.md b/Web/PWA-README.md deleted file mode 100644 index 5f28270..0000000 --- a/Web/PWA-README.md +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Web/README.md b/Web/README.md deleted file mode 100644 index 20c32a5..0000000 --- a/Web/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# email-bill - -This template should help get you started developing with Vue 3 in Vite. - -## Recommended IDE Setup - -[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). - -## Recommended Browser Setup - -- Chromium-based browsers (Chrome, Edge, Brave, etc.): - - [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd) - - [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters) -- Firefox: - - [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/) - - [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/) - -## Customize configuration - -See [Vite Configuration Reference](https://vite.dev/config/). - -## Project Setup - -```sh -pnpm install -``` - -### Compile and Hot-Reload for Development - -```sh -pnpm dev -``` - -### Compile and Minify for Production - -```sh -pnpm build -``` - -### Lint with [ESLint](https://eslint.org/) - -```sh -pnpm lint -``` diff --git a/Web/package.json b/Web/package.json index fd78880..04bae05 100644 --- a/Web/package.json +++ b/Web/package.json @@ -1,6 +1,6 @@ { "name": "email-bill", - "version": "0.0.0", + "version": "1.0.0", "private": true, "type": "module", "engines": { diff --git a/Web/public/manifest.json b/Web/public/manifest.json index 5e1c8ea..753bf19 100644 --- a/Web/public/manifest.json +++ b/Web/public/manifest.json @@ -3,7 +3,7 @@ "short_name": "账单", "description": "个人账单管理与邮件解析", "start_url": "/", - "display": "minimal-ui", + "display": "standalone", "background_color": "#ffffff", "theme_color": "#1989fa", "orientation": "portrait-primary", diff --git a/Web/src/api/notification.js b/Web/src/api/notification.js index c62b2e2..3916917 100644 --- a/Web/src/api/notification.js +++ b/Web/src/api/notification.js @@ -2,14 +2,14 @@ export function getVapidPublicKey() { return request({ - url: '/notification/vapid-public-key', + url: '/Notification/GetVapidPublicKey', method: 'get' }) } export function subscribe(data) { return request({ - url: '/notification/subscribe', + url: '/Notification/Subscribe', method: 'post', data }) @@ -17,7 +17,7 @@ export function subscribe(data) { export function testNotification(message) { return request({ - url: '/notification/test', + url: '/Notification/TestNotification', method: 'post', params: { message } }) diff --git a/Web/src/views/SettingView.vue b/Web/src/views/SettingView.vue index f0c43f2..1f51c6a 100644 --- a/Web/src/views/SettingView.vue +++ b/Web/src/views/SettingView.vue @@ -107,8 +107,13 @@ const handleNotificationToggle = async (checked) => { return } - const { data: { publicKey } } = await getVapidPublicKey() - const convertedVapidKey = urlBase64ToUint8Array(publicKey) + let { success, data, message } = await getVapidPublicKey() + + if (!success) { + throw new Error(message || '获取 VAPID 公钥失败') + } + + const convertedVapidKey = urlBase64ToUint8Array(data) const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, diff --git a/WebApi/Controllers/NotificationController.cs b/WebApi/Controllers/NotificationController.cs index 33663d8..4c719f5 100644 --- a/WebApi/Controllers/NotificationController.cs +++ b/WebApi/Controllers/NotificationController.cs @@ -1,27 +1,46 @@ namespace WebApi.Controllers; [ApiController] -[Route("api/[controller]")] +[Route("api/[controller]/[action]")] public class NotificationController(INotificationService notificationService) : ControllerBase { - [HttpGet("vapid-public-key")] - public async Task GetVapidPublicKey() + [HttpGet()] + public async Task> GetVapidPublicKey() { - var key = await notificationService.GetVapidPublicKeyAsync(); - return Ok(new { publicKey = key }); + try + { + var key = await notificationService.GetVapidPublicKeyAsync(); + return BaseResponse.Done(key); + } + catch (Exception ex) + { + return BaseResponse.Fail(ex.Message); + } } - [HttpPost("subscribe")] - public async Task Subscribe([FromBody] PushSubscriptionEntity subscription) + public async Task Subscribe([FromBody] PushSubscriptionEntity subscription) { - await notificationService.SubscribeAsync(subscription); - return Ok(); + try + { + await notificationService.SubscribeAsync(subscription); + return BaseResponse.Done(); + } + catch (Exception ex) + { + return BaseResponse.Fail(ex.Message); + } } - [HttpPost("test")] - public async Task TestNotification([FromQuery] string message) + public async Task TestNotification([FromQuery] string message) { - await notificationService.SendNotificationAsync(message); - return Ok(); + try + { + await notificationService.SendNotificationAsync(message); + return BaseResponse.Done(); + } + catch (Exception ex) + { + return BaseResponse.Fail(ex.Message); + } } }