This commit is contained in:
zlwu committed 2026-06-29 11:15:39 +08:00
1 parent 493f8d6756
commit d84f4b944c
406 files changed
+58954 -10376

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
import { useUserStore } from '@/store/modules/user'
export const CREATOR_DELETE_TIP = '仅创建人可删除'
/** 当前登录用户 ID(UUID 字符串) */
export function getCurrentUserId(): string {
const info = useUserStore().info as Record<string, unknown>
const id = info?.id ?? info?.userId ?? info?.user_id
if (id === undefined || id === null || id === '') return ''
return String(id)
}
/** 是否 super_admin */
export function isSuperAdmin(): boolean {
const info = useUserStore().info as Record<string, unknown>
const roles = (info?.roles as string[] | undefined) ?? []
const role = (info?.role as string | undefined) ?? ''
return role === 'super_admin' || roles.includes('super_admin')
}
export function rowCreatorId(row: Record<string, unknown> | null | undefined): string {
if (!row) return ''
const creator =
row.createBy ??
row.create_by ??
row.applicantId ??
row.applicant_id
if (creator === undefined || creator === null || creator === '') return ''
return String(creator)
}
/** 是否允许删除(仅创建人或 super_admin) */
export function canDeleteByCreator(
row: Record<string, unknown> | null | undefined,
currentUserId?: string
): boolean {
if (!row) return false
if (isSuperAdmin()) return true
const uid = (currentUserId ?? getCurrentUserId()).trim()
const creator = rowCreatorId(row)
if (!creator) return false
if (uid && creator === uid) return true
const info = useUserStore().info as Record<string, unknown>
const names = [info?.realName, info?.real_name, info?.userName, info?.username, info?.nickName]
.filter(Boolean)
.map(String)
return names.includes(creator)
}
/** 批量删除前过滤可删行 */
export function filterDeletableByCreator<T extends Record<string, unknown>>(
rows: T[],
currentUserId?: string
): T[] {
return rows.filter((row) => canDeleteByCreator(row, currentUserId))
}
/** 选中项是否全部可删 */
export function allRowsDeletableByCreator(
rows: Record<string, unknown>[],
currentUserId?: string
): boolean {
if (!rows.length) return false
return rows.every((row) => canDeleteByCreator(row, currentUserId))
}
+114
View File
@@ -32,6 +32,24 @@ export function getPlCarrierStatusTagType(status: string) {
return status === '1' ? 'success' : 'danger'
}
export function getPlCarrierAuditStatusLabel(status?: string) {
const map: Record<string, string> = {
pending: '待审核',
approved: '已通过',
rejected: '已驳回'
}
return status ? map[status] || status : '待审核'
}
export function getPlCarrierAuditStatusTagType(status?: string) {
const map: Record<string, string> = {
pending: 'warning',
approved: 'success',
rejected: 'danger'
}
return map[status || ''] || 'info'
}
export function getPlanProductSpec(product: { model?: string; packageSpec?: string }) {
return product.model || product.packageSpec || '—'
}
@@ -150,6 +168,21 @@ export function getPlYesNoLabel(value?: number | boolean | null) {
return value === 1 || value === true ? '是' : '否'
}
export function getPlHasInvoiceLabelFromSettlement(settlement?: {
invoiceNo?: string | null
invoiceDate?: string | null
invoiceAmount?: number | null
invoiceAttachmentUrls?: string | null
} | null) {
if (!settlement) return '—'
const hasInvoice =
Boolean(settlement.invoiceNo?.trim()) ||
Boolean(settlement.invoiceDate) ||
(settlement.invoiceAmount != null && Number(settlement.invoiceAmount) > 0) ||
Boolean(settlement.invoiceAttachmentUrls?.trim())
return hasInvoice ? '是' : '否'
}
/** 解析运输单司机回传附件(JSON 数组或逗号分隔) */
export function parsePlFeedbackImages(raw?: string | string[] | null): string[] {
if (!raw) return []
@@ -169,3 +202,84 @@ export function parsePlFeedbackImages(raw?: string | string[] | null): string[]
.map((item) => item.trim())
.filter(Boolean)
}
export function getPlRechargeTypeLabel(type: string) {
return type === 'etc' ? 'ETC' : type === 'fuel' ? '加油' : type
}
export function getPlRechargeTypeTagType(type: string) {
return type === 'etc' ? 'primary' : type === 'fuel' ? 'success' : 'info'
}
export function getPlRechargeApplyStatusLabel(status: string) {
const map: Record<string, string> = {
pending: '待发放',
disbursed: '已发放',
cancelled: '已作废'
}
return map[status] || status
}
export function getPlRechargeApplyStatusTagType(status: string) {
const map: Record<string, string> = {
pending: 'warning',
disbursed: 'success',
cancelled: 'info'
}
return map[status] || 'info'
}
export const PL_GAS_STATION_PRESETS = ['中石化', '线上etc-app', '百链']
export const PL_MAINTENANCE_TYPE_PRESETS = ['保养', '维修', '年检']
export function getPlMaintenanceTypeLabel(type: string) {
return type || '—'
}
export function getPlMaintenanceTypeTagType(type: string) {
const map: Record<string, string> = {
保养: 'success',
维修: 'warning',
年检: 'primary'
}
return map[type] || 'info'
}
export function getPlMaintenanceApplyStatusLabel(status: string) {
const map: Record<string, string> = {
pending: '待处理',
processed: '已处理',
cancelled: '已作废'
}
return map[status] || status
}
export function getPlMaintenanceApplyStatusTagType(status: string) {
const map: Record<string, string> = {
pending: 'warning',
processed: 'success',
cancelled: 'info'
}
return map[status] || 'info'
}
export const PL_UREA_UNIT_PRESETS = ['吨桶']
export function getPlUreaApplyStatusLabel(status: string) {
const map: Record<string, string> = {
pending: '待发放',
disbursed: '已发放',
cancelled: '已作废'
}
return map[status] || status
}
export function getPlUreaApplyStatusTagType(status: string) {
const map: Record<string, string> = {
pending: 'warning',
disbursed: 'success',
cancelled: 'info'
}
return map[status] || 'info'
}
+110
View File
@@ -0,0 +1,110 @@
import type { CertRow } from '@/api/pl'
export const PL_VEHICLE_CERT_PART_HEAD = 'head'
export const PL_VEHICLE_CERT_PART_TRAILER = 'trailer'
export const PL_VEHICLE_REQUIRED_CERT_NAMES = ['行驶证', '营运证'] as const
export const PL_VEHICLE_CERT_NAME_OPTIONS = [
'行驶证',
'营运证',
'道路运输证',
'驾驶证',
'押运员证',
'危化品从业资格证',
'保险单'
]
export type VehicleCertPart = typeof PL_VEHICLE_CERT_PART_HEAD | typeof PL_VEHICLE_CERT_PART_TRAILER
export function normalizeVehicleCertPart(part?: string | null): VehicleCertPart {
return part === PL_VEHICLE_CERT_PART_TRAILER ? PL_VEHICLE_CERT_PART_TRAILER : PL_VEHICLE_CERT_PART_HEAD
}
export function splitVehicleCertsByPart<T extends CertRow>(certList: T[] = []) {
const headCerts: T[] = []
const trailerCerts: T[] = []
for (const cert of certList) {
if (normalizeVehicleCertPart(cert.vehiclePart) === PL_VEHICLE_CERT_PART_TRAILER) {
trailerCerts.push(cert)
} else {
headCerts.push(cert)
}
}
return { headCerts, trailerCerts }
}
export function mergeVehicleCertsByPart<T extends CertRow>(
headCerts: T[],
trailerCerts: T[],
hasTrailer: boolean
) {
const normalizedHead = headCerts.map(cert => ({
...cert,
vehiclePart: PL_VEHICLE_CERT_PART_HEAD
}))
if (!hasTrailer) {
return normalizedHead
}
const normalizedTrailer = trailerCerts.map(cert => ({
...cert,
vehiclePart: PL_VEHICLE_CERT_PART_TRAILER
}))
return [...normalizedHead, ...normalizedTrailer]
}
function isCertFilled(cert?: CertRow) {
if (!cert) return false
return Boolean(
cert.certName?.trim() &&
cert.certNo?.trim() &&
cert.expireDate &&
cert.attachmentUrls?.trim()
)
}
export function validateVehicleRequiredCerts(options: {
headCerts: CertRow[]
trailerCerts: CertRow[]
hasTrailer: boolean
licensePlate: string
trailerNo: string
onError: (message: string) => void
}) {
const { headCerts, trailerCerts, hasTrailer, licensePlate, trailerNo, onError } = options
const parts: Array<{ label: string; certs: CertRow[] }> = [
{ label: licensePlate?.trim() || '主车', certs: headCerts }
]
if (hasTrailer) {
parts.push({ label: trailerNo?.trim() || '挂车', certs: trailerCerts })
}
for (const part of parts) {
for (const certName of PL_VEHICLE_REQUIRED_CERT_NAMES) {
const matched = part.certs.find(item => item.certName?.trim() === certName)
if (!isCertFilled(matched)) {
onError(`请完善「${part.label}」的${certName}(证号、有效期、附件均必填)`)
return false
}
}
}
for (const certs of [headCerts, ...(hasTrailer ? [trailerCerts] : [])]) {
for (const cert of certs) {
if (!cert.certName?.trim()) {
onError('证书名称不能为空')
return false
}
}
}
return true
}
export function filterVehicleCertsForSubmit<T extends CertRow>(
headCerts: T[],
trailerCerts: T[],
hasTrailer: boolean
) {
return mergeVehicleCertsByPart(headCerts, trailerCerts, hasTrailer)
}