refactor(品牌工具页): 抽取 formatDateTime 与 uploadPathsToJava 公共工具
- 新增 shared/utils/datetime.ts:13 个品牌页逐字重复的 formatDateTime 收敛为一处; 语义不同的 3 个变体(toLocaleString / 字符串切片 / 支持时间戳)保留不动 - 新增 shared/utils/upload-to-java.ts:10 个品牌页的上传循环收敛,api 依赖注入便于单测; 保留 uploadOss(品牌Tab)与 returnEmptyWhenUnavailable(跟价)两处行为差异 - 补 datetime / upload-to-java 单测 10 例 净减约 327 行;vue-tsc 构建与 690 个前端单测全通过
This commit is contained in:
@@ -257,6 +257,8 @@ import {
|
||||
type PriceTrackShopQueueItem,
|
||||
type PriceTrackTaskDetailVo,
|
||||
} from '@/shared/api/java-modules'
|
||||
import { formatDateTime } from '@/shared/utils/datetime'
|
||||
import { uploadPathsToJava } from '@/shared/utils/upload-to-java'
|
||||
|
||||
const ziniaoVersion = useZiniaoVersion()
|
||||
|
||||
@@ -336,19 +338,6 @@ function snapTask(item: PriceTrackHistoryItem) {
|
||||
return item.taskId ? taskSnapshots.value[item.taskId]?.task : undefined
|
||||
}
|
||||
|
||||
function formatDateTime(value?: string) {
|
||||
if (!value) return '-'
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) return value
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
|
||||
}
|
||||
|
||||
const pollTimer = ref<number | null>(null)
|
||||
const pollingInFlight = ref(false)
|
||||
let disposed = false
|
||||
@@ -511,7 +500,7 @@ async function selectAsinFile() {
|
||||
}
|
||||
try {
|
||||
asinFiles.value = paths
|
||||
asinUploadedFiles.value = await uploadAsinPathsToJava(paths)
|
||||
asinUploadedFiles.value = await uploadPathsToJava(getPywebviewApi(), paths, { returnEmptyWhenUnavailable: true })
|
||||
ElMessage.success(`已选择 ${paths.length} 个ASIN文件`)
|
||||
} catch (error) {
|
||||
// 上传失败时清空选择,避免本地路径残留被当作服务器路径提交给 Java
|
||||
@@ -537,7 +526,7 @@ async function selectAsinFolder() {
|
||||
}
|
||||
if (!(await passGuard(checkSelectedFiles(result.items, { allowedExtensions: EXCEL_CSV_EXTENSIONS })))) return
|
||||
asinFiles.value = result.items.map((item) => item.relativePath || item.absolutePath)
|
||||
asinUploadedFiles.value = await uploadAsinPathsToJava(result.items)
|
||||
asinUploadedFiles.value = await uploadPathsToJava(getPywebviewApi(), result.items, { returnEmptyWhenUnavailable: true })
|
||||
ElMessage.success(`已选择文件夹内 ${result.items.length} 个ASIN文件`)
|
||||
} catch (error) {
|
||||
// 上传失败时清空选择,避免残留上一批文件让用户误以为新文件已就绪
|
||||
@@ -550,24 +539,6 @@ async function selectAsinFolder() {
|
||||
|
||||
|
||||
// ========== 国家顺序相关 ==========
|
||||
async function uploadAsinPathsToJava(paths: Array<string | { absolutePath: string; relativePath?: string }>) {
|
||||
const api = getPywebviewApi()
|
||||
if (!api?.upload_file_to_java) {
|
||||
return []
|
||||
}
|
||||
const uploaded: UploadedJavaFile[] = []
|
||||
for (const item of paths) {
|
||||
const filePath = typeof item === 'string' ? item : item.absolutePath
|
||||
const relativePath = typeof item === 'string' ? undefined : item.relativePath
|
||||
const result = await api.upload_file_to_java(filePath, relativePath)
|
||||
if (!result?.success || !result.data) {
|
||||
throw new Error(result?.error || result?.message || `上传失败:${filePath}`)
|
||||
}
|
||||
uploaded.push(result.data)
|
||||
}
|
||||
return uploaded
|
||||
}
|
||||
|
||||
function resolveAsinRequestPaths() {
|
||||
// 提交上传返回的 fileKey(与去重/转换/采集等模块一致):服务端按 key 反查上传临时目录,
|
||||
// 不依赖上传返回的 localPath 绝对路径形态——安全加固后服务端按拼接解析绝对路径会失败。
|
||||
|
||||
Reference in New Issue
Block a user