fix
This commit is contained in:
@@ -19,9 +19,9 @@ public interface ITransactionRecordRepository : IBaseRepository<TransactionRecor
|
|||||||
/// <param name="month">筛选月份</param>
|
/// <param name="month">筛选月份</param>
|
||||||
/// <returns>交易记录列表、最后发生时间和最后ID</returns>
|
/// <returns>交易记录列表、最后发生时间和最后ID</returns>
|
||||||
Task<(List<TransactionRecord> list, DateTime? lastOccurredAt, long lastId)> GetPagedListAsync(
|
Task<(List<TransactionRecord> list, DateTime? lastOccurredAt, long lastId)> GetPagedListAsync(
|
||||||
DateTime? lastOccurredAt,
|
DateTime? lastOccurredAt,
|
||||||
long? lastId,
|
long? lastId,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
string? searchKeyword = null,
|
string? searchKeyword = null,
|
||||||
string? classify = null,
|
string? classify = null,
|
||||||
TransactionType? type = null,
|
TransactionType? type = null,
|
||||||
@@ -130,7 +130,7 @@ public interface ITransactionRecordRepository : IBaseRepository<TransactionRecor
|
|||||||
/// <param name="keyword">关键词</param>
|
/// <param name="keyword">关键词</param>
|
||||||
/// <returns>匹配的交易记录列表</returns>
|
/// <returns>匹配的交易记录列表</returns>
|
||||||
Task<List<TransactionRecord>> QueryByWhereAsync(string sql);
|
Task<List<TransactionRecord>> QueryByWhereAsync(string sql);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行完整的SQL查询
|
/// 执行完整的SQL查询
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -163,9 +163,9 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(List<TransactionRecord> list, DateTime? lastOccurredAt, long lastId)> GetPagedListAsync(
|
public async Task<(List<TransactionRecord> list, DateTime? lastOccurredAt, long lastId)> GetPagedListAsync(
|
||||||
DateTime? lastOccurredAt,
|
DateTime? lastOccurredAt,
|
||||||
long? lastId,
|
long? lastId,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
string? searchKeyword = null,
|
string? searchKeyword = null,
|
||||||
string? classify = null,
|
string? classify = null,
|
||||||
TransactionType? type = null,
|
TransactionType? type = null,
|
||||||
@@ -175,25 +175,24 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
|||||||
var query = FreeSql.Select<TransactionRecord>();
|
var query = FreeSql.Select<TransactionRecord>();
|
||||||
|
|
||||||
// 如果提供了搜索关键词,则添加搜索条件
|
// 如果提供了搜索关键词,则添加搜索条件
|
||||||
if (!string.IsNullOrWhiteSpace(searchKeyword))
|
query = query.WhereIf(!string.IsNullOrWhiteSpace(searchKeyword),
|
||||||
{
|
t => t.Reason.Contains(searchKeyword!) ||
|
||||||
query = query.Where(t => t.Reason.Contains(searchKeyword) ||
|
t.Classify.Contains(searchKeyword!) ||
|
||||||
t.Classify.Contains(searchKeyword) ||
|
t.Card.Contains(searchKeyword!) ||
|
||||||
t.Card.Contains(searchKeyword) ||
|
t.ImportFrom.Contains(searchKeyword!));
|
||||||
t.ImportFrom.Contains(searchKeyword));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按分类筛选
|
// 按分类筛选
|
||||||
if (!string.IsNullOrWhiteSpace(classify))
|
if (!string.IsNullOrWhiteSpace(classify))
|
||||||
{
|
{
|
||||||
|
if (classify == "未分类")
|
||||||
|
{
|
||||||
|
classify = string.Empty;
|
||||||
|
}
|
||||||
query = query.Where(t => t.Classify == classify);
|
query = query.Where(t => t.Classify == classify);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按交易类型筛选
|
// 按交易类型筛选
|
||||||
if (type.HasValue)
|
query = query.WhereIf(type.HasValue, t => t.Type == type!.Value);
|
||||||
{
|
|
||||||
query = query.Where(t => t.Type == type.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按年月筛选
|
// 按年月筛选
|
||||||
if (year.HasValue && month.HasValue)
|
if (year.HasValue && month.HasValue)
|
||||||
@@ -370,7 +369,7 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
|||||||
{
|
{
|
||||||
var dt = await FreeSql.Ado.ExecuteDataTableAsync(completeSql);
|
var dt = await FreeSql.Ado.ExecuteDataTableAsync(completeSql);
|
||||||
var result = new List<dynamic>();
|
var result = new List<dynamic>();
|
||||||
|
|
||||||
foreach (System.Data.DataRow row in dt.Rows)
|
foreach (System.Data.DataRow row in dt.Rows)
|
||||||
{
|
{
|
||||||
var expando = new System.Dynamic.ExpandoObject() as IDictionary<string, object>;
|
var expando = new System.Dynamic.ExpandoObject() as IDictionary<string, object>;
|
||||||
@@ -380,7 +379,7 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
|||||||
}
|
}
|
||||||
result.Add(expando);
|
result.Add(expando);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public async Task<MonthlyStatistics> GetMonthlyStatisticsAsync(int year, int month)
|
public async Task<MonthlyStatistics> GetMonthlyStatisticsAsync(int year, int month)
|
||||||
@@ -401,7 +400,7 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
|||||||
foreach (var record in records)
|
foreach (var record in records)
|
||||||
{
|
{
|
||||||
var amount = Math.Abs(record.Amount);
|
var amount = Math.Abs(record.Amount);
|
||||||
|
|
||||||
if (record.Type == TransactionType.Expense)
|
if (record.Type == TransactionType.Expense)
|
||||||
{
|
{
|
||||||
statistics.TotalExpense += amount;
|
statistics.TotalExpense += amount;
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ public class ImportService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用正则表达式提取退款金额
|
// 使用正则表达式提取退款金额
|
||||||
var regex = new System.Text.RegularExpressions.Regex(@"¥(-?\d+(\.\d+)?)");
|
var regex = new Regex(@"¥(-?\d+(\.\d+)?)");
|
||||||
var match = regex.Match(status);
|
var match = regex.Match(status);
|
||||||
if (match.Success && decimal.TryParse(match.Groups[1].Value, out var refundAmount))
|
if (match.Success && decimal.TryParse(match.Groups[1].Value, out var refundAmount))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,19 +3,19 @@
|
|||||||
<div class="app-root">
|
<div class="app-root">
|
||||||
<RouterView />
|
<RouterView />
|
||||||
<van-tabbar v-model="active" v-show="showTabbar">
|
<van-tabbar v-model="active" v-show="showTabbar">
|
||||||
<van-tabbar-item icon="notes" to="/calendar">
|
<van-tabbar-item name="ccalendar" icon="notes" to="/calendar">
|
||||||
日历
|
日历
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
<van-tabbar-item icon="chart-trending-o" to="/statistics">
|
<van-tabbar-item name="statistics" icon="chart-trending-o" to="/statistics">
|
||||||
统计
|
统计
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
<van-tabbar-item icon="balance-list" to="/" @click="handleTabClick('/')">
|
<van-tabbar-item name="balance" icon="balance-list" to="/" @click="handleTabClick('/')">
|
||||||
账单
|
账单
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
<van-tabbar-item icon="records" to="/email" @click="handleTabClick('/email')">
|
<van-tabbar-item name="email" icon="records" to="/email" @click="handleTabClick('/email')">
|
||||||
邮件
|
邮件
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
<van-tabbar-item icon="setting" to="/setting">
|
<van-tabbar-item name="setting" icon="setting" to="/setting">
|
||||||
设置
|
设置
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
</van-tabbar>
|
</van-tabbar>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { RouterView, useRoute } from 'vue-router'
|
import { RouterView, useRoute } from 'vue-router'
|
||||||
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
||||||
import '@/styles/common.css'
|
import '@/styles/common.css'
|
||||||
|
|
||||||
const updateVh = () => {
|
const updateVh = () => {
|
||||||
@@ -61,7 +61,7 @@ const showTabbar = computed(() => {
|
|||||||
route.path === '/statistics'
|
route.path === '/statistics'
|
||||||
})
|
})
|
||||||
|
|
||||||
const active = ref(0)
|
const active = ref('')
|
||||||
const theme = ref('light')
|
const theme = ref('light')
|
||||||
|
|
||||||
// 检测系统深色模式
|
// 检测系统深色模式
|
||||||
@@ -76,8 +76,32 @@ onMounted(() => {
|
|||||||
updateTheme()
|
updateTheme()
|
||||||
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
mediaQuery.addEventListener('change', updateTheme)
|
mediaQuery.addEventListener('change', updateTheme)
|
||||||
|
setActive(route.path)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听路由变化调整
|
||||||
|
watch(() => route.path, (newPath) => {
|
||||||
|
setActive(newPath)
|
||||||
|
})
|
||||||
|
|
||||||
|
const setActive = (path) => {
|
||||||
|
active.value = (() => {
|
||||||
|
switch (path) {
|
||||||
|
case '/calendar':
|
||||||
|
return 'ccalendar'
|
||||||
|
case '/statistics':
|
||||||
|
return 'statistics'
|
||||||
|
case '/email':
|
||||||
|
return 'email'
|
||||||
|
case '/setting':
|
||||||
|
return 'setting'
|
||||||
|
default:
|
||||||
|
return 'balance'
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
console.log(active.value, path)
|
||||||
|
}
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (mediaQuery) {
|
if (mediaQuery) {
|
||||||
mediaQuery.removeEventListener('change', updateTheme)
|
mediaQuery.removeEventListener('change', updateTheme)
|
||||||
|
|||||||
@@ -152,3 +152,12 @@
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 账单列表滚动容器 */
|
||||||
|
.bills-scroll-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
<p v-if="dateTransactions.length">共 {{ dateTransactions.length }} 笔交易</p>
|
<p v-if="dateTransactions.length">共 {{ dateTransactions.length }} 笔交易</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="bills-scroll-container">
|
||||||
<TransactionList
|
<TransactionList
|
||||||
:transactions="dateTransactions"
|
:transactions="dateTransactions"
|
||||||
:loading="listLoading"
|
:loading="listLoading"
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
@click="viewDetail"
|
@click="viewDetail"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</van-popup>
|
</van-popup>
|
||||||
|
|
||||||
<!-- 交易详情组件 -->
|
<!-- 交易详情组件 -->
|
||||||
|
|||||||
@@ -141,13 +141,15 @@
|
|||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<h3 style="margin: 16px;">关联账单列表</h3>
|
<h3 style="margin: 16px;">关联账单列表</h3>
|
||||||
</div>
|
</div>
|
||||||
<TransactionList
|
<div class="bills-scroll-container">
|
||||||
:transactions="transactionList"
|
<TransactionList
|
||||||
:loading="false"
|
:transactions="transactionList"
|
||||||
:finished="true"
|
:loading="false"
|
||||||
:show-delete="false"
|
:finished="true"
|
||||||
@click="handleTransactionClick"
|
:show-delete="false"
|
||||||
/>
|
@click="handleTransactionClick"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</van-popup>
|
</van-popup>
|
||||||
|
|
||||||
@@ -434,7 +436,13 @@ onMounted(() => {
|
|||||||
|
|
||||||
.transaction-list-popup {
|
.transaction-list-popup {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-header{
|
||||||
|
padding: 16px;
|
||||||
|
border-bottom: 1px solid #ebedf0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.email-content {
|
.email-content {
|
||||||
|
|||||||
@@ -562,7 +562,7 @@ const goToAnalysis = () => {
|
|||||||
|
|
||||||
// 打开分类账单列表
|
// 打开分类账单列表
|
||||||
const goToCategoryBills = (classify, type) => {
|
const goToCategoryBills = (classify, type) => {
|
||||||
selectedClassify.value = classify || ''
|
selectedClassify.value = classify || '未分类'
|
||||||
selectedType.value = type
|
selectedType.value = type
|
||||||
selectedCategoryTitle.value = `${classify || '未分类'} - ${type === 0 ? '支出' : '收入'}`
|
selectedCategoryTitle.value = `${classify || '未分类'} - ${type === 0 ? '支出' : '收入'}`
|
||||||
|
|
||||||
@@ -1076,14 +1076,6 @@ onActivated(() => {
|
|||||||
color: var(--van-text-color-2);
|
color: var(--van-text-color-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 账单列表滚动容器 */
|
|
||||||
.bills-scroll-container {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修复深色模式下van组件的背景色 */
|
/* 修复深色模式下van组件的背景色 */
|
||||||
.category-bills :deep(.van-list) {
|
.category-bills :deep(.van-list) {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class TransactionRecordController(
|
|||||||
/// 获取交易记录列表(分页)
|
/// 获取交易记录列表(分页)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<PagedResponse<Entity.TransactionRecord>> GetListAsync(
|
public async Task<PagedResponse<TransactionRecord>> GetListAsync(
|
||||||
[FromQuery] DateTime? lastOccurredAt = null,
|
[FromQuery] DateTime? lastOccurredAt = null,
|
||||||
[FromQuery] long? lastId = null,
|
[FromQuery] long? lastId = null,
|
||||||
[FromQuery] string? searchKeyword = null,
|
[FromQuery] string? searchKeyword = null,
|
||||||
@@ -39,7 +39,7 @@ public class TransactionRecordController(
|
|||||||
month);
|
month);
|
||||||
var total = await transactionRepository.GetTotalCountAsync();
|
var total = await transactionRepository.GetTotalCountAsync();
|
||||||
|
|
||||||
return new PagedResponse<Entity.TransactionRecord>
|
return new PagedResponse<TransactionRecord>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = list.ToArray(),
|
Data = list.ToArray(),
|
||||||
@@ -51,7 +51,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取交易记录列表失败,时间: {LastTime}, ID: {LastId}", lastOccurredAt, lastId);
|
logger.LogError(ex, "获取交易记录列表失败,时间: {LastTime}, ID: {LastId}", lastOccurredAt, lastId);
|
||||||
return PagedResponse<Entity.TransactionRecord>.Fail($"获取交易记录列表失败: {ex.Message}");
|
return PagedResponse<TransactionRecord>.Fail($"获取交易记录列表失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,17 +59,17 @@ public class TransactionRecordController(
|
|||||||
/// 根据ID获取交易记录详情
|
/// 根据ID获取交易记录详情
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public async Task<BaseResponse<Entity.TransactionRecord>> GetByIdAsync(long id)
|
public async Task<BaseResponse<TransactionRecord>> GetByIdAsync(long id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var transaction = await transactionRepository.GetByIdAsync(id);
|
var transaction = await transactionRepository.GetByIdAsync(id);
|
||||||
if (transaction == null)
|
if (transaction == null)
|
||||||
{
|
{
|
||||||
return BaseResponse<Entity.TransactionRecord>.Fail("交易记录不存在");
|
return BaseResponse<TransactionRecord>.Fail("交易记录不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BaseResponse<Entity.TransactionRecord>
|
return new BaseResponse<TransactionRecord>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = transaction
|
Data = transaction
|
||||||
@@ -78,7 +78,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取交易记录详情失败,交易ID: {TransactionId}", id);
|
logger.LogError(ex, "获取交易记录详情失败,交易ID: {TransactionId}", id);
|
||||||
return BaseResponse<Entity.TransactionRecord>.Fail($"获取交易记录详情失败: {ex.Message}");
|
return BaseResponse<TransactionRecord>.Fail($"获取交易记录详情失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,12 +86,12 @@ public class TransactionRecordController(
|
|||||||
/// 根据邮件ID获取交易记录列表
|
/// 根据邮件ID获取交易记录列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet("{emailId}")]
|
[HttpGet("{emailId}")]
|
||||||
public async Task<BaseResponse<List<Entity.TransactionRecord>>> GetByEmailIdAsync(long emailId)
|
public async Task<BaseResponse<List<TransactionRecord>>> GetByEmailIdAsync(long emailId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var transactions = await transactionRepository.GetByEmailIdAsync(emailId);
|
var transactions = await transactionRepository.GetByEmailIdAsync(emailId);
|
||||||
return new BaseResponse<List<Entity.TransactionRecord>>
|
return new BaseResponse<List<TransactionRecord>>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = transactions
|
Data = transactions
|
||||||
@@ -100,7 +100,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取邮件交易记录失败,邮件ID: {EmailId}", emailId);
|
logger.LogError(ex, "获取邮件交易记录失败,邮件ID: {EmailId}", emailId);
|
||||||
return BaseResponse<List<Entity.TransactionRecord>>.Fail($"获取邮件交易记录失败: {ex.Message}");
|
return BaseResponse<List<TransactionRecord>>.Fail($"获取邮件交易记录失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ public class TransactionRecordController(
|
|||||||
return BaseResponse.Fail("交易时间格式不正确");
|
return BaseResponse.Fail("交易时间格式不正确");
|
||||||
}
|
}
|
||||||
|
|
||||||
var transaction = new Entity.TransactionRecord
|
var transaction = new TransactionRecord
|
||||||
{
|
{
|
||||||
OccurredAt = occurredAt,
|
OccurredAt = occurredAt,
|
||||||
Reason = dto.Reason ?? string.Empty,
|
Reason = dto.Reason ?? string.Empty,
|
||||||
@@ -416,7 +416,7 @@ public class TransactionRecordController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 第三步:将查询结果序列化为JSON,直接传递给AI生成分析报告
|
// 第三步:将查询结果序列化为JSON,直接传递给AI生成分析报告
|
||||||
var dataJson = System.Text.Json.JsonSerializer.Serialize(queryResults, new System.Text.Json.JsonSerializerOptions
|
var dataJson = System.Text.Json.JsonSerializer.Serialize(queryResults, new JsonSerializerOptions
|
||||||
{
|
{
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||||
@@ -482,13 +482,13 @@ public class TransactionRecordController(
|
|||||||
/// 获取指定日期的交易记录
|
/// 获取指定日期的交易记录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<BaseResponse<List<Entity.TransactionRecord>>> GetByDateAsync([FromQuery] string date)
|
public async Task<BaseResponse<List<TransactionRecord>>> GetByDateAsync([FromQuery] string date)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!DateTime.TryParse(date, out var targetDate))
|
if (!DateTime.TryParse(date, out var targetDate))
|
||||||
{
|
{
|
||||||
return BaseResponse<List<Entity.TransactionRecord>>.Fail("日期格式不正确");
|
return BaseResponse<List<TransactionRecord>>.Fail("日期格式不正确");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当天的开始和结束时间
|
// 获取当天的开始和结束时间
|
||||||
@@ -497,7 +497,7 @@ public class TransactionRecordController(
|
|||||||
|
|
||||||
var records = await transactionRepository.GetByDateRangeAsync(startDate, endDate);
|
var records = await transactionRepository.GetByDateRangeAsync(startDate, endDate);
|
||||||
|
|
||||||
return new BaseResponse<List<Entity.TransactionRecord>>
|
return new BaseResponse<List<TransactionRecord>>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = records
|
Data = records
|
||||||
@@ -506,7 +506,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取指定日期的交易记录失败,日期: {Date}", date);
|
logger.LogError(ex, "获取指定日期的交易记录失败,日期: {Date}", date);
|
||||||
return BaseResponse<List<Entity.TransactionRecord>>.Fail($"获取指定日期的交易记录失败: {ex.Message}");
|
return BaseResponse<List<TransactionRecord>>.Fail($"获取指定日期的交易记录失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,12 +536,12 @@ public class TransactionRecordController(
|
|||||||
/// 获取未分类的账单列表
|
/// 获取未分类的账单列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<BaseResponse<List<Entity.TransactionRecord>>> GetUnclassifiedAsync([FromQuery] int pageSize = 10)
|
public async Task<BaseResponse<List<TransactionRecord>>> GetUnclassifiedAsync([FromQuery] int pageSize = 10)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var records = await transactionRepository.GetUnclassifiedAsync(pageSize);
|
var records = await transactionRepository.GetUnclassifiedAsync(pageSize);
|
||||||
return new BaseResponse<List<Entity.TransactionRecord>>
|
return new BaseResponse<List<TransactionRecord>>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = records
|
Data = records
|
||||||
@@ -550,7 +550,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取未分类账单列表失败");
|
logger.LogError(ex, "获取未分类账单列表失败");
|
||||||
return BaseResponse<List<Entity.TransactionRecord>>.Fail($"获取未分类账单列表失败: {ex.Message}");
|
return BaseResponse<List<TransactionRecord>>.Fail($"获取未分类账单列表失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +574,7 @@ public class TransactionRecordController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取指定ID的账单
|
// 获取指定ID的账单
|
||||||
var records = new List<Entity.TransactionRecord>();
|
var records = new List<TransactionRecord>();
|
||||||
foreach (var id in request.TransactionIds)
|
foreach (var id in request.TransactionIds)
|
||||||
{
|
{
|
||||||
var record = await transactionRepository.GetByIdAsync(id);
|
var record = await transactionRepository.GetByIdAsync(id);
|
||||||
@@ -702,14 +702,14 @@ public class TransactionRecordController(
|
|||||||
/// 获取按交易摘要分组的统计信息(支持分页)
|
/// 获取按交易摘要分组的统计信息(支持分页)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<PagedResponse<Repository.ReasonGroupDto>> GetReasonGroupsAsync(
|
public async Task<PagedResponse<ReasonGroupDto>> GetReasonGroupsAsync(
|
||||||
[FromQuery] int pageIndex = 1,
|
[FromQuery] int pageIndex = 1,
|
||||||
[FromQuery] int pageSize = 20)
|
[FromQuery] int pageSize = 20)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (list, total) = await transactionRepository.GetReasonGroupsAsync(pageIndex, pageSize);
|
var (list, total) = await transactionRepository.GetReasonGroupsAsync(pageIndex, pageSize);
|
||||||
return new PagedResponse<Repository.ReasonGroupDto>
|
return new PagedResponse<ReasonGroupDto>
|
||||||
{
|
{
|
||||||
Success = true,
|
Success = true,
|
||||||
Data = list.ToArray(),
|
Data = list.ToArray(),
|
||||||
@@ -719,7 +719,7 @@ public class TransactionRecordController(
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "获取交易摘要分组失败");
|
logger.LogError(ex, "获取交易摘要分组失败");
|
||||||
return PagedResponse<Repository.ReasonGroupDto>.Fail($"获取交易摘要分组失败: {ex.Message}");
|
return PagedResponse<ReasonGroupDto>.Fail($"获取交易摘要分组失败: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,21 +780,33 @@ public class TransactionRecordController(
|
|||||||
{{categoryInfo}}
|
{{categoryInfo}}
|
||||||
|
|
||||||
你需要分析用户的需求,提取以下信息:
|
你需要分析用户的需求,提取以下信息:
|
||||||
1. 查询SQL, 根据用户的描述生成SQL Where 子句,用于查询交易记录。例如:Reason LIKE '%关键词%'
|
1. 查询SQL, 根据用户的描述生成完整SQL语句,用于查询交易记录。例如:SELECT * FROM TransactionRecord WHERE Reason LIKE '%关键词%' OR Classify LIKE '%关键词2%' LIMIT 500
|
||||||
Table Schema:
|
[重要Table Schema:]
|
||||||
|
```
|
||||||
TransactionRecord (
|
TransactionRecord (
|
||||||
Id LONG,
|
Id LONG,
|
||||||
Reason STRING,
|
Reason STRING NOT NULL,
|
||||||
Amount DECIMAL,
|
Amount DECIMAL,
|
||||||
RefundAmount DECIMAL,
|
RefundAmount DECIMAL,
|
||||||
Balance DECIMAL,
|
Balance DECIMAL,
|
||||||
OccurredAt DATETIME,
|
OccurredAt DATETIME,
|
||||||
EmailMessageId LONG,
|
EmailMessageId LONG,
|
||||||
Type INT,
|
Type INT,
|
||||||
Classify STRING,
|
Classify STRING NOT NULL,
|
||||||
ImportNo STRING,
|
ImportNo STRING NOT NULL,
|
||||||
ImportFrom STRING
|
ImportFrom STRING NOT NULL
|
||||||
)
|
)
|
||||||
|
```
|
||||||
|
[重要]
|
||||||
|
如果用户没有限制,则最多查询500条记录;如果用户指定了时间范围,请在SQL中加入时间过滤条件。
|
||||||
|
[重要SQL限制]
|
||||||
|
必须是SELECT * FROM TransactionRecord 开头的SQL语句。
|
||||||
|
当前日期:{{DateTime.Now:yyyy年M月d日}}
|
||||||
|
[重要SQLite日期函数]
|
||||||
|
- 提取年份:strftime('%Y', OccurredAt)
|
||||||
|
- 提取月份:strftime('%m', OccurredAt)
|
||||||
|
- 提取日期:strftime('%Y-%m-%d', OccurredAt)
|
||||||
|
- 不要使用 YEAR()、MONTH()、DAY() 函数,SQLite不支持
|
||||||
2. 目标交易类型(0:支出, 1:收入, 2:不计入收支)
|
2. 目标交易类型(0:支出, 1:收入, 2:不计入收支)
|
||||||
3. 目标分类名称(必须从上面的分类列表中选择)
|
3. 目标分类名称(必须从上面的分类列表中选择)
|
||||||
|
|
||||||
@@ -835,7 +847,7 @@ public class TransactionRecordController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据关键词查询交易记录
|
// 根据关键词查询交易记录
|
||||||
var allRecords = await transactionRepository.QueryByWhereAsync(analysisInfo.Sql);
|
var allRecords = await transactionRepository.ExecuteRawSqlAsync(analysisInfo.Sql);
|
||||||
logger.LogInformation("NLP分析查询到 {Count} 条记录,SQL: {Sql}", allRecords.Count, analysisInfo.Sql);
|
logger.LogInformation("NLP分析查询到 {Count} 条记录,SQL: {Sql}", allRecords.Count, analysisInfo.Sql);
|
||||||
|
|
||||||
// 为每条记录预设分类
|
// 为每条记录预设分类
|
||||||
|
|||||||
Reference in New Issue
Block a user