fix
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 37s
Docker Build & Deploy / Deploy to Production (push) Successful in 8s

This commit is contained in:
2026-01-02 18:51:28 +08:00
parent e250a7df2f
commit 5c76e9287e
9 changed files with 60 additions and 66 deletions

View File

@@ -661,6 +661,15 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
var minAmount = absAmount - 5; var minAmount = absAmount - 5;
var maxAmount = absAmount + 5; var maxAmount = absAmount + 5;
var currentRecord = await FreeSql.Select<TransactionRecord>()
.Where(t => t.Id == currentId)
.FirstAsync();
if (currentRecord == null)
{
return new List<TransactionRecord>();
}
var list = await FreeSql.Select<TransactionRecord>() var list = await FreeSql.Select<TransactionRecord>()
.Where(t => t.Id != currentId) .Where(t => t.Id != currentId)
.Where(t => t.Type != currentType) .Where(t => t.Type != currentType)
@@ -668,7 +677,9 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
.Take(50) .Take(50)
.ToListAsync(); .ToListAsync();
return list.OrderBy(t => 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<int> UpdateCategoryNameAsync(string oldName, string newName, TransactionType type) public async Task<int> UpdateCategoryNameAsync(string oldName, string newName, TransactionType type)

View File

@@ -24,6 +24,10 @@ public class SmartHandleService(
// 获取指定ID的账单作为样本 // 获取指定ID的账单作为样本
var sampleRecords = await transactionRepository.GetByIdsAsync(transactionIds); var sampleRecords = await transactionRepository.GetByIdsAsync(transactionIds);
sampleRecords = sampleRecords
.Where(x => string.IsNullOrEmpty(x.Classify))
.ToArray();
if (sampleRecords.Length == 0) if (sampleRecords.Length == 0)
{ {
// await WriteEventAsync("error", "找不到指定的账单"); // await WriteEventAsync("error", "找不到指定的账单");

View File

@@ -1 +0,0 @@

View File

@@ -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
```

View File

@@ -1,6 +1,6 @@
{ {
"name": "email-bill", "name": "email-bill",
"version": "0.0.0", "version": "1.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"engines": { "engines": {

View File

@@ -3,7 +3,7 @@
"short_name": "账单", "short_name": "账单",
"description": "个人账单管理与邮件解析", "description": "个人账单管理与邮件解析",
"start_url": "/", "start_url": "/",
"display": "minimal-ui", "display": "standalone",
"background_color": "#ffffff", "background_color": "#ffffff",
"theme_color": "#1989fa", "theme_color": "#1989fa",
"orientation": "portrait-primary", "orientation": "portrait-primary",

View File

@@ -2,14 +2,14 @@
export function getVapidPublicKey() { export function getVapidPublicKey() {
return request({ return request({
url: '/notification/vapid-public-key', url: '/Notification/GetVapidPublicKey',
method: 'get' method: 'get'
}) })
} }
export function subscribe(data) { export function subscribe(data) {
return request({ return request({
url: '/notification/subscribe', url: '/Notification/Subscribe',
method: 'post', method: 'post',
data data
}) })
@@ -17,7 +17,7 @@ export function subscribe(data) {
export function testNotification(message) { export function testNotification(message) {
return request({ return request({
url: '/notification/test', url: '/Notification/TestNotification',
method: 'post', method: 'post',
params: { message } params: { message }
}) })

View File

@@ -107,8 +107,13 @@ const handleNotificationToggle = async (checked) => {
return return
} }
const { data: { publicKey } } = await getVapidPublicKey() let { success, data, message } = await getVapidPublicKey()
const convertedVapidKey = urlBase64ToUint8Array(publicKey)
if (!success) {
throw new Error(message || '获取 VAPID 公钥失败')
}
const convertedVapidKey = urlBase64ToUint8Array(data)
const subscription = await registration.pushManager.subscribe({ const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true, userVisibleOnly: true,

View File

@@ -1,27 +1,46 @@
namespace WebApi.Controllers; namespace WebApi.Controllers;
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]/[action]")]
public class NotificationController(INotificationService notificationService) : ControllerBase public class NotificationController(INotificationService notificationService) : ControllerBase
{ {
[HttpGet("vapid-public-key")] [HttpGet()]
public async Task<IActionResult> GetVapidPublicKey() public async Task<BaseResponse<string>> GetVapidPublicKey()
{ {
var key = await notificationService.GetVapidPublicKeyAsync(); try
return Ok(new { publicKey = key }); {
var key = await notificationService.GetVapidPublicKeyAsync();
return BaseResponse<string>.Done(key);
}
catch (Exception ex)
{
return BaseResponse<string>.Fail(ex.Message);
}
} }
[HttpPost("subscribe")] public async Task<BaseResponse> Subscribe([FromBody] PushSubscriptionEntity subscription)
public async Task<IActionResult> Subscribe([FromBody] PushSubscriptionEntity subscription)
{ {
await notificationService.SubscribeAsync(subscription); try
return Ok(); {
await notificationService.SubscribeAsync(subscription);
return BaseResponse.Done();
}
catch (Exception ex)
{
return BaseResponse.Fail(ex.Message);
}
} }
[HttpPost("test")] public async Task<BaseResponse> TestNotification([FromQuery] string message)
public async Task<IActionResult> TestNotification([FromQuery] string message)
{ {
await notificationService.SendNotificationAsync(message); try
return Ok(); {
await notificationService.SendNotificationAsync(message);
return BaseResponse.Done();
}
catch (Exception ex)
{
return BaseResponse.Fail(ex.Message);
}
} }
} }