This commit is contained in:
zlwu committed 2026-07-01 18:52:26 +08:00
1 parent 7c838cfb2d
commit 8e70047f4c
161 files changed
+16659 -10436

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
import type { InventoryRecord } from '@/api/db/inventory'
import type { TransportInventoryLink } from '@/api/pl'
import { formatDateTime } from '@/utils/format'
import { formatDate } from '@/utils/format'
const SITE_INSTRUCTION = '说明:请打开链接上传现场附件并填写备注。'
@@ -27,7 +27,7 @@ export function buildSiteSummaryFromInventoryLinks(options: {
const planNo = options.planNo || options.records[0]?.planNo
if (planNo) lines.push(`计划号:${planNo}`)
if (options.licensePlate) lines.push(`车牌:${options.licensePlate}`)
const time = formatDateTime(options.pickupTime) || options.planDate
const time = formatDate(options.pickupTime) || options.planDate
if (time) lines.push(`时间:${time}`)
const validRecords = options.records.filter(item => item.siteUrl)
+20 -1
View File
@@ -1,5 +1,5 @@
import { ElMessage } from 'element-plus'
import { fetchAttachmentDownloadUrl } from '@/api/admin'
import { fetchAttachmentDownloadUrl, fetchAttachmentPreviewUrl } from '@/api/admin'
export type AttachmentDownloadItem = {
fileUrl?: string
@@ -34,6 +34,25 @@ function triggerAnchorDownload(href: string, fileName: string) {
document.body.removeChild(a)
}
/** 附件预览:优先走后端预签名 inline URL,供 PDF iframe 等内联展示。 */
export async function resolveAttachmentPreviewUrl(
file: AttachmentDownloadItem,
options?: { fullFileUrl?: (url: string) => string }
): Promise<string> {
const fileUrl = String(file.fileUrl || '').trim()
if (!fileUrl) return ''
const resolveUrl = options?.fullFileUrl || ((url: string) => url)
try {
const res = await fetchAttachmentPreviewUrl({ fileUrl, fileName: file.fileName })
if (res?.previewUrl) return res.previewUrl
} catch {
// 预签名失败时回退直连
}
return resolveUrl(fileUrl)
}
/** 附件下载:优先走后端预签名 URL,保证跨域场景下保留原始文件名与后缀。 */
export async function downloadAttachmentFile(
file: AttachmentDownloadItem,
+4
View File
@@ -35,3 +35,7 @@ export function parseTime(time?: string | number | Date | null, pattern = '{y}-{
export function formatDateTime(time?: string | null) {
return parseTime(time)
}
export function formatDate(time?: string | number | Date | null) {
return parseTime(time, '{y}-{m}-{d}')
}
+1 -3
View File
@@ -24,9 +24,7 @@
import { useWorktabStore } from '@/store/modules/worktab'
import { RouteLocationNormalized } from 'vue-router'
import { isIframe, isWorkbenchRoute } from './route'
import { useSettingStore } from '@/store/modules/setting'
import { IframeRouteManager } from '@/router/core'
import { useCommon } from '@/hooks/core/useCommon'
/**
* 根据当前路由信息设置工作标签页(worktab)
@@ -54,7 +52,7 @@ export const setWorktab = (to: RouteLocationNormalized): void => {
query
})
}
} else if (useSettingStore().showWorkTab || path === useCommon().homePath.value) {
} else {
worktabStore.openTab({
title: meta.title as string,
icon: meta.icon as string,
+79 -1
View File
@@ -1,5 +1,5 @@
import type { AppRouteRecord } from '@/types/router'
import { getFirstMenuPath } from '@/utils/navigation/route'
import { getFirstMenuPath, getFirstSecondLevelMenuPath, isIframe } from '@/utils/navigation/route'
import { filterSidebarRoutes } from '@/utils/router/sidebar-menu-filter'
/** 门户顶栏一级模块展示顺序(与路由注册顺序无关) */
@@ -14,6 +14,9 @@ export const PORTAL_TOP_MODULE_ORDER = [
export type PortalTopModulePath = (typeof PORTAL_TOP_MODULE_ORDER)[number]
/** 门户默认一级模块(登录后 / 关闭全部标签等场景的默认落点) */
export const PORTAL_DEFAULT_MODULE_PATH: PortalTopModulePath = '/crm'
export function isDashboardMenuItem(item: AppRouteRecord): boolean {
const path = String(item.path ?? '')
const title = String(item.meta?.title ?? '')
@@ -101,3 +104,78 @@ export function getFirstAccessiblePath(module: AppRouteRecord): string {
return module.path || '/'
}
function findIframeSubMenus(currentPath: string, menuList: AppRouteRecord[]): AppRouteRecord[] {
const hasPath = (items: AppRouteRecord[]): boolean => {
for (const item of items) {
if (item.path === currentPath) {
return true
}
if (item.children?.length && hasPath(item.children)) {
return true
}
}
return false
}
for (const menu of menuList) {
if (menu.children?.length && hasPath(menu.children)) {
return menu.children
}
}
return []
}
/** 当前路由所属一级模块下的侧栏/顶栏子菜单(二三级) */
export function resolvePortalSubMenus(
menuList: AppRouteRecord[],
routePath: string
): AppRouteRecord[] {
const allMenus = menuList || []
const activePath = String(routePath)
if (isIframe(activePath)) {
return findIframeSubMenus(activePath, allMenus)
}
const currentTopPath = resolveTopModulePath(activePath)
if (!currentTopPath) {
return []
}
const currentMenu = allMenus.find((menu) => menu.path === currentTopPath)
return currentMenu?.children ?? []
}
/** 门户默认首页:优先 CRM 管理模块首个可访问页 */
export function getPortalDefaultHomePath(menuList: AppRouteRecord[]): string {
const tops = filterPortalTopModules(menuList)
const defaultModule =
tops.find((item) => item.path === PORTAL_DEFAULT_MODULE_PATH) || tops[0]
if (defaultModule) {
return getFirstAccessiblePath(defaultModule)
}
return getFirstSecondLevelMenuPath(menuList) || getFirstMenuPath(menuList)
}
/** WorkTab 全部关闭后:当前模块首个二级路径,无则模块首个可访问页 */
export function getPortalDefaultPathForRoute(
menuList: AppRouteRecord[],
routePath: string
): string {
const module = resolveActivePortalModule(menuList, routePath)
if (!module) {
return getPortalDefaultHomePath(menuList)
}
const children = filterSidebarRoutes(resolvePortalSubMenus(menuList, routePath))
if (children.length) {
const childPath = getFirstMenuPath(children, module.path)
if (childPath) {
return childPath
}
}
return getFirstAccessiblePath(module)
}