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:
2026-09-13 23:16:59 +08:00
parent b70557a077
commit 882ccdac12
18 changed files with 210 additions and 377 deletions
+20
View File
@@ -0,0 +1,20 @@
/**
* 时间展示工具(前端各工具页统一使用)。
*/
/**
* 把后端时间串格式化为 `YYYY-MM-DD HH:mm:ss`(本地时区)。
* 空值返回 '-';无法解析时原样返回,避免把后端原始串吞掉。
*/
export function formatDateTime(value?: string): 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}`
}
@@ -0,0 +1,47 @@
import type { PywebviewApi, UploadedJavaFile } from '../bridges/pywebview.ts'
/** 待上传条目:本机绝对路径字符串,或展开文件夹得到的 { absolutePath, relativePath }。 */
export interface UploadPathItem {
absolutePath: string
relativePath?: string
}
export interface UploadPathsToJavaOptions {
/** 透传给桥的 uploadOss 参数;需要把文件落到 OSS 的模块传 true。 */
uploadOss?: boolean
/** 缺少上传桥时返回空数组而非抛错(个别模块的降级语义)。 */
returnEmptyWhenUnavailable?: boolean
}
/**
* 逐个把本机文件上传给 Java,返回上传结果列表。
*
* 任一个失败即整体抛错(不返回半成品),由调用方统一提示并清空已选文件,
* 避免残留上一批让用户误以为新文件已就绪。
*
* api 由调用方传入(通常是 `getPywebviewApi()`),便于脱离桌面桥单测。
*/
export async function uploadPathsToJava(
api: PywebviewApi | undefined,
paths: ReadonlyArray<string | UploadPathItem>,
options: UploadPathsToJavaOptions = {},
): Promise<UploadedJavaFile[]> {
const upload = api?.upload_file_to_java
if (!upload) {
if (options.returnEmptyWhenUnavailable) {
return []
}
throw new Error('当前桌面端未提供文件上传能力')
}
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 upload(filePath, relativePath, options.uploadOss)
if (!result?.success || !result.data) {
throw new Error(result?.error || result?.message || `上传失败:${filePath}`)
}
uploaded.push(result.data)
}
return uploaded
}