大量的代码格式化
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 1m10s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 1m10s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
This commit is contained in:
@@ -1,13 +1,8 @@
|
||||
<template>
|
||||
<div class="page-container-flex smart-classification">
|
||||
<van-nav-bar
|
||||
title="智能分类"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
/>
|
||||
|
||||
<div class="scroll-content" style="padding-top: 5px;">
|
||||
<van-nav-bar title="智能分类" left-text="返回" left-arrow @click-left="onClickLeft" />
|
||||
|
||||
<div class="scroll-content" style="padding-top: 5px">
|
||||
<!-- 统计信息 -->
|
||||
<div class="stats-info">
|
||||
<span class="stats-label">未分类账单 </span>
|
||||
@@ -23,13 +18,13 @@
|
||||
/>
|
||||
|
||||
<!-- 底部安全距离 -->
|
||||
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))"></div>
|
||||
<div style="height: calc(50px + env(safe-area-inset-bottom, 0px))" />
|
||||
</div>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="bottom-button">
|
||||
<van-button
|
||||
type="primary"
|
||||
<van-button
|
||||
type="primary"
|
||||
:loading="classifying"
|
||||
:disabled="selectedCount === 0"
|
||||
round
|
||||
@@ -38,9 +33,9 @@
|
||||
>
|
||||
{{ classifying ? '分类中...' : `开始分类 (${selectedCount}组)` }}
|
||||
</van-button>
|
||||
|
||||
<van-button
|
||||
type="success"
|
||||
|
||||
<van-button
|
||||
type="success"
|
||||
:disabled="!hasChanges || classifying"
|
||||
round
|
||||
class="action-btn"
|
||||
@@ -56,11 +51,7 @@
|
||||
import { ref, computed, onMounted, nextTick } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showToast, showLoadingToast, closeToast, showConfirmDialog } from 'vant'
|
||||
import {
|
||||
getUnclassifiedCount,
|
||||
smartClassify,
|
||||
batchUpdateClassify
|
||||
} from '@/api/transactionRecord'
|
||||
import { getUnclassifiedCount, smartClassify, batchUpdateClassify } from '@/api/transactionRecord'
|
||||
import ReasonGroupList from '@/components/ReasonGroupList.vue'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -74,7 +65,9 @@ const suppressDataChanged = ref(false)
|
||||
|
||||
// 计算已选中的数量
|
||||
const selectedCount = computed(() => {
|
||||
if (!groupListRef.value) return 0
|
||||
if (!groupListRef.value) {
|
||||
return 0
|
||||
}
|
||||
return groupListRef.value.getSelectedReasons().size
|
||||
})
|
||||
|
||||
@@ -114,10 +107,12 @@ const onClickLeft = () => {
|
||||
if (hasChanges.value) {
|
||||
showConfirmDialog({
|
||||
title: '提示',
|
||||
message: '有未保存的分类结果,确定要离开吗?',
|
||||
}).then(() => {
|
||||
router.back()
|
||||
}).catch(() => {})
|
||||
message: '有未保存的分类结果,确定要离开吗?'
|
||||
})
|
||||
.then(() => {
|
||||
router.back()
|
||||
})
|
||||
.catch(() => {})
|
||||
} else {
|
||||
router.back()
|
||||
}
|
||||
@@ -125,17 +120,19 @@ const onClickLeft = () => {
|
||||
|
||||
// 开始智能分类
|
||||
const startClassify = async () => {
|
||||
if (!groupListRef.value) return
|
||||
|
||||
if (!groupListRef.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取所有选中分组
|
||||
const selectedGroups = groupListRef.value.getList(true)
|
||||
|
||||
|
||||
// 获取所有选中分组的账单ID
|
||||
const idsToClassify = []
|
||||
for (const group of selectedGroups) {
|
||||
idsToClassify.push(...group.transactionIds)
|
||||
}
|
||||
|
||||
|
||||
if (idsToClassify.length === 0) {
|
||||
showToast('请先选择要分类的账单组')
|
||||
return
|
||||
@@ -149,13 +146,13 @@ const startClassify = async () => {
|
||||
|
||||
classifying.value = true
|
||||
classifyBuffer.value = ''
|
||||
|
||||
|
||||
// 用于存储分类结果的临时对象
|
||||
const classifyResults = new Map()
|
||||
|
||||
|
||||
try {
|
||||
const response = await smartClassify(idsToClassify)
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
@@ -166,23 +163,27 @@ const startClassify = async () => {
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
|
||||
if (done) break
|
||||
|
||||
|
||||
if (done) {
|
||||
break
|
||||
}
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
const lines = buffer.split('\n\n')
|
||||
buffer = lines.pop() || ''
|
||||
|
||||
for (const line of lines) {
|
||||
if (!line.trim()) continue
|
||||
|
||||
if (!line.trim()) {
|
||||
continue
|
||||
}
|
||||
|
||||
const eventMatch = line.match(/^event: (.+)$/m)
|
||||
const dataMatch = line.match(/^data: (.+)$/m)
|
||||
|
||||
|
||||
if (eventMatch && dataMatch) {
|
||||
const eventType = eventMatch[1]
|
||||
const data = dataMatch[1]
|
||||
|
||||
|
||||
handleSSEEvent(eventType, data, classifyResults)
|
||||
}
|
||||
}
|
||||
@@ -215,8 +216,9 @@ const handleSSEEvent = (eventType, data, classifyResults) => {
|
||||
let braceCount = 0
|
||||
let closeBrace = -1
|
||||
for (let i = openBrace; i < classifyBuffer.value.length; i++) {
|
||||
if (classifyBuffer.value[i] === '{') braceCount++
|
||||
else if (classifyBuffer.value[i] === '}') {
|
||||
if (classifyBuffer.value[i] === '{') {
|
||||
braceCount++
|
||||
} else if (classifyBuffer.value[i] === '}') {
|
||||
braceCount--
|
||||
if (braceCount === 0) {
|
||||
closeBrace = i
|
||||
@@ -227,7 +229,7 @@ const handleSSEEvent = (eventType, data, classifyResults) => {
|
||||
|
||||
if (closeBrace !== -1) {
|
||||
const jsonStr = classifyBuffer.value.substring(openBrace, closeBrace + 1)
|
||||
|
||||
|
||||
try {
|
||||
const result = JSON.parse(jsonStr)
|
||||
if (result.id && groupListRef.value) {
|
||||
@@ -235,7 +237,7 @@ const handleSSEEvent = (eventType, data, classifyResults) => {
|
||||
classify: result.Classify || '',
|
||||
type: result.Type !== undefined ? result.Type : null
|
||||
})
|
||||
|
||||
|
||||
// 更新组件内的分组显示状态
|
||||
const groups = groupListRef.value.getList()
|
||||
for (const group of groups) {
|
||||
@@ -260,7 +262,7 @@ const handleSSEEvent = (eventType, data, classifyResults) => {
|
||||
} catch (e) {
|
||||
console.error('JSON解析失败:', e)
|
||||
}
|
||||
|
||||
|
||||
classifyBuffer.value = classifyBuffer.value.substring(closeBrace + 1)
|
||||
startIndex = 0
|
||||
} else {
|
||||
@@ -283,12 +285,14 @@ const handleSSEEvent = (eventType, data, classifyResults) => {
|
||||
|
||||
// 保存分类
|
||||
const saveClassifications = async () => {
|
||||
if (!groupListRef.value) return
|
||||
|
||||
if (!groupListRef.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// 收集所有已分类的账单
|
||||
const groups = groupListRef.value.getList()
|
||||
const itemsToUpdate = []
|
||||
|
||||
|
||||
for (const group of groups) {
|
||||
if (group.sampleClassify) {
|
||||
// 为该分组的所有账单添加分类
|
||||
@@ -362,4 +366,4 @@ onMounted(async () => {
|
||||
:deep(.van-nav-bar) {
|
||||
background: transparent !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user