大量的代码格式化
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:
@@ -11,7 +11,7 @@
|
||||
>
|
||||
<template v-if="!loading && !saving">
|
||||
<van-icon :name="buttonIcon" />
|
||||
<span style="margin-left: 4px;">{{ buttonText }}</span>
|
||||
<span style="margin-left: 4px">{{ buttonText }}</span>
|
||||
</template>
|
||||
</van-button>
|
||||
</template>
|
||||
@@ -52,28 +52,42 @@ const hasClassifiedResults = computed(() => {
|
||||
|
||||
// 按钮类型
|
||||
const buttonType = computed(() => {
|
||||
if (saving.value) return 'warning'
|
||||
if (loading.value) return 'primary'
|
||||
if (hasClassifiedResults.value) return 'success'
|
||||
if (saving.value) {
|
||||
return 'warning'
|
||||
}
|
||||
if (loading.value) {
|
||||
return 'primary'
|
||||
}
|
||||
if (hasClassifiedResults.value) {
|
||||
return 'success'
|
||||
}
|
||||
return 'primary'
|
||||
})
|
||||
|
||||
// 按钮图标
|
||||
const buttonIcon = computed(() => {
|
||||
if (hasClassifiedResults.value) return 'success'
|
||||
if (hasClassifiedResults.value) {
|
||||
return 'success'
|
||||
}
|
||||
return 'fire'
|
||||
})
|
||||
|
||||
// 按钮文字(非加载状态)
|
||||
const buttonText = computed(() => {
|
||||
if (hasClassifiedResults.value) return '保存分类'
|
||||
if (hasClassifiedResults.value) {
|
||||
return '保存分类'
|
||||
}
|
||||
return '智能分类'
|
||||
})
|
||||
|
||||
// 加载中文字
|
||||
const loadingText = computed(() => {
|
||||
if (saving.value) return '保存中...'
|
||||
if (loading.value) return '分类中...'
|
||||
if (saving.value) {
|
||||
return '保存中...'
|
||||
}
|
||||
if (loading.value) {
|
||||
return '分类中...'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
@@ -92,8 +106,10 @@ const handleClick = () => {
|
||||
* 保存分类结果
|
||||
*/
|
||||
const handleSaveClassify = async () => {
|
||||
if (saving.value || loading.value) return
|
||||
|
||||
if (saving.value || loading.value) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
saving.value = true
|
||||
showToast({
|
||||
@@ -104,27 +120,27 @@ const handleSaveClassify = async () => {
|
||||
})
|
||||
|
||||
// 准备批量更新数据
|
||||
const items = classifiedResults.value.map(item => ({
|
||||
const items = classifiedResults.value.map((item) => ({
|
||||
id: item.id,
|
||||
classify: item.classify,
|
||||
type: item.type
|
||||
}))
|
||||
|
||||
const response = await batchUpdateClassify(items)
|
||||
|
||||
|
||||
closeToast()
|
||||
|
||||
|
||||
if (response.success) {
|
||||
showToast({
|
||||
type: 'success',
|
||||
message: `保存成功,已更新 ${items.length} 条记录`,
|
||||
duration: 2000
|
||||
})
|
||||
|
||||
|
||||
// 清空已分类结果
|
||||
classifiedResults.value = []
|
||||
isAllCompleted.value = false
|
||||
|
||||
|
||||
// 通知父组件刷新数据
|
||||
emit('save')
|
||||
} else {
|
||||
@@ -161,7 +177,7 @@ const handleSmartClassify = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
if(lockClassifiedResults.value) {
|
||||
if (lockClassifiedResults.value) {
|
||||
showToast('当前有分类任务正在进行,请稍后再试')
|
||||
loading.value = false
|
||||
return
|
||||
@@ -170,10 +186,10 @@ const handleSmartClassify = async () => {
|
||||
// 清空之前的分类结果
|
||||
isAllCompleted.value = false
|
||||
classifiedResults.value = []
|
||||
|
||||
|
||||
const batchSize = 3
|
||||
let processedCount = 0
|
||||
|
||||
|
||||
try {
|
||||
lockClassifiedResults.value = true
|
||||
// 等待父组件的 beforeClassify 事件处理完成(如果有返回 Promise)
|
||||
@@ -200,10 +216,10 @@ const handleSmartClassify = async () => {
|
||||
// 分批处理
|
||||
for (let i = 0; i < allTransactions.length; i += batchSize) {
|
||||
const batch = allTransactions.slice(i, i + batchSize)
|
||||
const transactionIds = batch.map(t => t.id)
|
||||
const transactionIds = batch.map((t) => t.id)
|
||||
const currentBatch = Math.floor(i / batchSize) + 1
|
||||
const totalBatches = Math.ceil(allTransactions.length / batchSize)
|
||||
|
||||
|
||||
// 更新批次进度
|
||||
closeToast()
|
||||
toastInstance = showToast({
|
||||
@@ -214,7 +230,7 @@ const handleSmartClassify = async () => {
|
||||
})
|
||||
|
||||
const response = await smartClassify(transactionIds)
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('智能分类请求失败')
|
||||
}
|
||||
@@ -228,23 +244,27 @@ const handleSmartClassify = async () => {
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read()
|
||||
|
||||
if (done) break
|
||||
|
||||
|
||||
if (done) {
|
||||
break
|
||||
}
|
||||
|
||||
buffer += decoder.decode(value, { stream: true })
|
||||
|
||||
|
||||
// 处理完整的事件(SSE格式:event: type\ndata: data\n\n)
|
||||
const events = buffer.split('\n\n')
|
||||
buffer = events.pop() || '' // 保留最后一个不完整的部分
|
||||
|
||||
|
||||
for (const eventBlock of events) {
|
||||
if (!eventBlock.trim()) continue
|
||||
|
||||
if (!eventBlock.trim()) {
|
||||
continue
|
||||
}
|
||||
|
||||
try {
|
||||
const lines = eventBlock.split('\n')
|
||||
let eventType = ''
|
||||
let eventData = ''
|
||||
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('event: ')) {
|
||||
eventType = line.slice(7).trim()
|
||||
@@ -252,7 +272,7 @@ const handleSmartClassify = async () => {
|
||||
eventData = line.slice(6).trim()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (eventType === 'start') {
|
||||
// 开始分类
|
||||
closeToast()
|
||||
@@ -267,23 +287,23 @@ const handleSmartClassify = async () => {
|
||||
// 收到分类结果
|
||||
const data = JSON.parse(eventData)
|
||||
processedCount++
|
||||
|
||||
|
||||
// 记录分类结果
|
||||
classifiedResults.value.push({
|
||||
id: data.id,
|
||||
classify: data.Classify,
|
||||
type: data.Type
|
||||
})
|
||||
|
||||
|
||||
// 实时更新交易记录的分类信息
|
||||
const index = props.transactions.findIndex(t => t.id === data.id)
|
||||
const index = props.transactions.findIndex((t) => t.id === data.id)
|
||||
if (index !== -1) {
|
||||
const transaction = props.transactions[index]
|
||||
transaction.upsetedClassify = data.Classify
|
||||
transaction.upsetedType = data.Type
|
||||
emit('notifyDonedTransactionId', data.id)
|
||||
}
|
||||
|
||||
|
||||
// 限制Toast更新频率,避免频繁的DOM操作
|
||||
const now = Date.now()
|
||||
if (now - lastUpdateTime > updateInterval) {
|
||||
@@ -310,7 +330,7 @@ const handleSmartClassify = async () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 所有批次完成
|
||||
closeToast()
|
||||
toastInstance = null
|
||||
@@ -344,18 +364,18 @@ const handleSmartClassify = async () => {
|
||||
|
||||
const removeClassifiedTransaction = (transactionId) => {
|
||||
// 从已分类结果中移除指定ID的项
|
||||
classifiedResults.value = classifiedResults.value.filter(item => item.id !== transactionId)
|
||||
classifiedResults.value = classifiedResults.value.filter((item) => item.id !== transactionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置组件状态
|
||||
*/
|
||||
const reset = () => {
|
||||
if(lockClassifiedResults.value) {
|
||||
if (lockClassifiedResults.value) {
|
||||
showToast('当前有分类任务正在进行,无法重置')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
isAllCompleted.value = false
|
||||
classifiedResults.value = []
|
||||
loading.value = false
|
||||
@@ -365,8 +385,7 @@ const reset = () => {
|
||||
defineExpose({
|
||||
reset,
|
||||
removeClassifiedTransaction
|
||||
});
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user