删除品牌

This commit is contained in:
super
2026-03-27 21:32:00 +08:00
parent ea212c8931
commit 5dd7a92cf5
22 changed files with 675 additions and 214 deletions

View File

@@ -6,7 +6,7 @@
<aside class="left-panel">
<div class="section-title">选择文件</div>
<div class="upload-zone">
<div class="hint">上传删除品牌 Excel无论是直接上传文件还是上传文件夹批量导入都会按每个 Excel 文件名匹配紫鸟店铺</div>
<div class="hint">上传删除品牌 Excel无论是直接上传文件还是上传文件夹批量导入都会按每个 Excel 文件名作为店铺</div>
<div class="btns">
<button type="button" class="opt-btn" @click="selectFiles">选择 Excel 文件</button>
<button type="button" class="opt-btn" @click="selectFolder">选择文件夹</button>
@@ -29,7 +29,7 @@
<input type="checkbox" checked disabled />
<div>
<span class="label">文件名作为店铺名</span>
<div class="desc">例如 鲍丽明.xlsx 匹配紫鸟店铺 鲍丽明选择文件夹时也仍按每个 Excel 文件名匹配</div>
<div class="desc">例如 鲍丽明.xlsx 解析为店铺 鲍丽明当前先不联动紫鸟</div>
</div>
</label>
@@ -44,8 +44,8 @@
<label class="radio-item active">
<input type="checkbox" checked disabled />
<div>
<span class="label">大表仅返回预览</span>
<div class="desc">当前最多展示前 200 避免大文件直接拖慢页面</div>
<span class="label">按国家分组去重</span>
<div class="desc">解析后按国家返回并在每个国家内按 ASIN 去重保留首次出现的状态</div>
</div>
</label>
</div>
@@ -55,7 +55,7 @@
{{ running ? '解析中...' : '开始解析' }}
</button>
<span class="loading-msg">
{{ running ? '正在读取删除品牌数据并匹配紫鸟店铺,请稍候…' : '解析后会在右侧展示预览数据和紫鸟店铺打开链接' }}
{{ running ? '正在读取删除品牌数据,请稍候…' : '解析后会在右侧展示按国家分组的去重结果' }}
</span>
</div>
</aside>
@@ -84,13 +84,13 @@
</div>
<div v-if="resultItems.length === 0" class="empty-tasks">
暂无删除品牌结果完成解析后会在这里展示店铺匹配结果和预览数据
暂无删除品牌结果完成解析后会在这里展示按国家分组的去重结果
</div>
<ul v-else class="task-list clean-result-list">
<li
v-for="item in resultItems"
:key="`${item.resultId || item.sourceFilename}-${item.shopId || ''}`"
:key="`${item.resultId || item.taskId || item.sourceFilename}`"
class="task-item split-result-item"
>
<div class="left split-result-main">
@@ -98,8 +98,8 @@
<div class="files">店铺名{{ item.shopName || '-' }}</div>
<div class="files">匹配结果{{ item.matched ? `已匹配 ${item.shopId || ''}` : '未匹配到紫鸟店铺' }}</div>
<div v-if="item.platform" class="files">平台{{ item.platform }}</div>
<div v-if="item.totalRows !== undefined" class="time">预览 {{ item.previewRows?.length || 0 }} / {{ item.totalRows }} </div>
<div v-if="item.truncated" class="files">数据较大当前仅展示前 200 </div>
<div v-if="item.countryCount !== undefined" class="files">国家数{{ item.countryCount }}</div>
<div v-if="item.totalRows !== undefined" class="time">去重后 {{ item.totalRows }} </div>
<div v-if="item.previewRows?.length" class="files split-entry-list delete-brand-preview">
{{ formatPreview(item.previewRows) }}
</div>
@@ -116,7 +116,7 @@
class="download"
@click="openShop(item.openStoreUrl)"
>
打开店铺
打开紫鸟
</button>
<button
v-if="item.resultId"
@@ -241,7 +241,6 @@ async function submitRun() {
})
summary.value = result
resultItems.value = result.items || []
await loadHistory()
ElMessage.success('删除品牌解析完成')
} catch (error) {
ElMessage.error(error instanceof Error ? error.message : '执行失败')

View File

@@ -127,6 +127,37 @@ export interface DeleteBrandPreviewRow {
status: string
}
export interface DeleteBrandCountryAsinItem {
rowIndex: number
asin: string
status: string
}
export interface DeleteBrandCountryGroup {
country: string
asinCount: number
items: DeleteBrandCountryAsinItem[]
}
export interface DeleteBrandCountryResultItem {
asin: string
status?: string
}
export interface DeleteBrandProcessedCountry {
country: string
items: DeleteBrandCountryResultItem[]
}
export interface DeleteBrandResultFile {
sourceFilename: string
countries: DeleteBrandProcessedCountry[]
}
export interface DeleteBrandSubmitResultRequest {
files: DeleteBrandResultFile[]
}
export interface DeleteBrandResultItem {
resultId?: number
sourceFilename: string
@@ -135,6 +166,9 @@ export interface DeleteBrandResultItem {
shopId?: string
platform?: string
openStoreUrl?: string
taskId?: number
countryCount?: number
countries?: DeleteBrandCountryGroup[]
totalRows?: number
truncated?: boolean
previewRows?: DeleteBrandPreviewRow[]
@@ -277,6 +311,10 @@ export function deleteDeleteBrandHistory(resultId: number) {
}))
}
export function submitDeleteBrandResult(taskId: number, request: DeleteBrandSubmitResultRequest) {
return unwrapJavaResponse(post<JavaApiResponse<null>, DeleteBrandSubmitResultRequest>(`${JAVA_API_PREFIX}/delete-brand/tasks/${taskId}/result`, request))
}
export function getJavaDownloadUrl(path: string) {
const raw = path.startsWith('http://') || path.startsWith('https://') ? path : `${JAVA_API_PREFIX}${path}`
const separator = raw.includes('?') ? '&' : '?'