优化地图编辑中的字段管理
This commit is contained in:
@@ -2,8 +2,8 @@ import { computed, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { fetchQuickEntryKeys, saveQuickEntryKeys } from '@/api/dashboardQuickEntries'
|
||||
import {
|
||||
defaultQuickKeys, getQuickEntryCatalog, MAX_QUICK_ENTRIES,
|
||||
normalizeQuickKeys, resolveQuickEntry, type QuickEntryDef
|
||||
defaultQuickKeys, finalizeQuickKeys, getQuickEntryCatalog, isMandatoryQuickKey,
|
||||
MAX_QUICK_ENTRIES, normalizeQuickKeys, resolveQuickEntry, type QuickEntryDef
|
||||
} from '@/config/quickEntries'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import type { Scope } from '@/types/auth'
|
||||
@@ -20,8 +20,10 @@ export function useDashboardQuickEntries() {
|
||||
|
||||
/** 空列表仅在「尚未自定义」(usingDefaults) 时回退系统默认;用户主动清空则保持为空 */
|
||||
function effectiveKeys(): string[] {
|
||||
if (keys.value.length > 0) return keys.value
|
||||
return usingDefaults.value ? defaultQuickKeys(scope.value as Scope) : []
|
||||
const base = keys.value.length > 0
|
||||
? keys.value
|
||||
: (usingDefaults.value ? defaultQuickKeys(scope.value as Scope) : [])
|
||||
return finalizeQuickKeys(base, scope.value as Scope)
|
||||
}
|
||||
|
||||
function filterByPermission(list: string[]): string[] {
|
||||
@@ -63,8 +65,8 @@ export function useDashboardQuickEntries() {
|
||||
const dto = await fetchQuickEntryKeys(userId.value, scope.value)
|
||||
const loaded = normalizeQuickKeys(dto.keys)
|
||||
keys.value = loaded.length > 0
|
||||
? loaded
|
||||
: (dto.usingDefaults ? defaultQuickKeys(scope.value as Scope) : [])
|
||||
? finalizeQuickKeys(loaded, scope.value as Scope)
|
||||
: (dto.usingDefaults ? defaultQuickKeys(scope.value as Scope) : finalizeQuickKeys([], scope.value as Scope))
|
||||
usingDefaults.value = dto.usingDefaults
|
||||
} catch (e) {
|
||||
keys.value = defaultQuickKeys(scope.value as Scope)
|
||||
@@ -76,13 +78,14 @@ export function useDashboardQuickEntries() {
|
||||
}
|
||||
|
||||
async function persist(nextKeys: string[]) {
|
||||
const finalized = finalizeQuickKeys(nextKeys, scope.value as Scope)
|
||||
if (!userId.value) {
|
||||
keys.value = nextKeys
|
||||
keys.value = finalized
|
||||
return
|
||||
}
|
||||
try {
|
||||
const dto = await saveQuickEntryKeys(userId.value, scope.value, normalizeQuickKeys(nextKeys))
|
||||
keys.value = normalizeQuickKeys(dto.keys)
|
||||
const dto = await saveQuickEntryKeys(userId.value, scope.value, finalized)
|
||||
keys.value = finalizeQuickKeys(normalizeQuickKeys(dto.keys), scope.value as Scope)
|
||||
usingDefaults.value = dto.usingDefaults
|
||||
} catch (e) {
|
||||
ElMessage.error(`保存快捷入口失败:${e instanceof Error ? e.message : String(e)}`)
|
||||
@@ -105,6 +108,10 @@ export function useDashboardQuickEntries() {
|
||||
}
|
||||
|
||||
async function removeKey(key: string) {
|
||||
if (isMandatoryQuickKey(key, scope.value as Scope)) {
|
||||
ElMessage.warning('该快捷入口为系统默认项,不可移除')
|
||||
return
|
||||
}
|
||||
const base = [...effectiveKeys()]
|
||||
await persist(base.filter((k) => k !== key))
|
||||
ElMessage.success('已移除快捷入口')
|
||||
@@ -140,6 +147,7 @@ export function useDashboardQuickEntries() {
|
||||
addKey,
|
||||
removeKey,
|
||||
swapKeys,
|
||||
openPicker
|
||||
openPicker,
|
||||
isMandatoryQuickKey: (key: string) => isMandatoryQuickKey(key, scope.value as Scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { computed, ref, watch, type Ref } from 'vue'
|
||||
import { listSimpleFields } from '@/api/simpleField'
|
||||
import type { SimpleFieldCategory, SimpleFieldRecord } from '@/types/simpleField'
|
||||
|
||||
export function fieldCategoryForMapKind(kind: 'site' | 'track' | 'car' | null): SimpleFieldCategory | null {
|
||||
if (kind === 'site') return 'siteFields'
|
||||
if (kind === 'track') return 'trackFields'
|
||||
if (kind === 'car') return 'carFields'
|
||||
return null
|
||||
}
|
||||
|
||||
/** 按 key 去重(同 key 多条车型定义时保留第一条)。 */
|
||||
function dedupeByKey(rows: SimpleFieldRecord[]): SimpleFieldRecord[] {
|
||||
const seen = new Set<string>()
|
||||
const out: SimpleFieldRecord[] = []
|
||||
for (const row of rows) {
|
||||
if (seen.has(row.key)) continue
|
||||
seen.add(row.key)
|
||||
out.push(row)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function normalizeCarTypeToken(v: string | null | undefined): string {
|
||||
return (v ?? '').trim().replace(/^UI/i, '')
|
||||
}
|
||||
|
||||
function shortCarType(v: string): string {
|
||||
const s = v.trim()
|
||||
const i = s.lastIndexOf('.')
|
||||
return i >= 0 ? s.slice(i + 1) : s
|
||||
}
|
||||
|
||||
function filterRowsByCarType(rows: SimpleFieldRecord[], current: string | null | undefined): SimpleFieldRecord[] {
|
||||
const token = shortCarType(normalizeCarTypeToken(current)).toLowerCase()
|
||||
if (!token) return []
|
||||
return rows.filter((r) => shortCarType(r.carType).toLowerCase() === token)
|
||||
}
|
||||
|
||||
export function useSimpleFieldCatalog(
|
||||
kind: Ref<'site' | 'track' | 'car' | null>,
|
||||
carType?: Ref<string | null | undefined>
|
||||
) {
|
||||
const loading = ref(false)
|
||||
const records = ref<SimpleFieldRecord[]>([])
|
||||
|
||||
const fieldType = computed(() => fieldCategoryForMapKind(kind.value))
|
||||
|
||||
const byKey = computed(() => {
|
||||
const map = new Map<string, SimpleFieldRecord>()
|
||||
for (const row of records.value) map.set(row.key, row)
|
||||
return map
|
||||
})
|
||||
|
||||
async function reload() {
|
||||
const ft = fieldType.value
|
||||
if (!ft) {
|
||||
records.value = []
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
// 车辆:为兼容 shortName / assembly.shortName 等不同 car_type 存储格式,先拉 carFields 再前端匹配当前车型。
|
||||
if (ft === 'carFields') {
|
||||
const all = await listSimpleFields(ft)
|
||||
records.value = dedupeByKey(filterRowsByCarType(all, carType?.value))
|
||||
} else {
|
||||
const rows = await listSimpleFields(ft)
|
||||
records.value = dedupeByKey(rows)
|
||||
}
|
||||
} catch {
|
||||
records.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(fieldType, () => { void reload() }, { immediate: true })
|
||||
|
||||
function labelForKey(key: string): string {
|
||||
const row = byKey.value.get(key)
|
||||
return row?.chinese?.trim() || row?.english?.trim() || '—'
|
||||
}
|
||||
|
||||
function defaultValueForKey(key: string): string {
|
||||
return byKey.value.get(key)?.value ?? ''
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
records,
|
||||
fieldType,
|
||||
byKey,
|
||||
reload,
|
||||
labelForKey,
|
||||
defaultValueForKey
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user