import { ref } from 'vue' import { togetherCallback } from '@/utils' import { autoSetModeCallback, createTemploraryID } from './sys' import { defaultStyle, getTaggingStyle } from './tagging-style' import { initTaggingPositionsByTagging, saveTaggingPositions, recoverTaggingPositions, backupTaggingPositions, taggingPositions, getTaggingPositions } from './tagging-positions' import { saveTaggingStyles, recoverTaggingStyles, backupTaggingStyles, taggingStyles } from './tagging-style' import { fetchTaggings, postAddTagging, postDeleteTagging, postUpdateTagging, uploadFile } from '@/api' import { deleteStoreItem, addStoreItem, updateStoreItem, fetchStoreItems, saveStoreItems, recoverStoreItems } from '@/utils' import type { Tagging as STagging } from '@/api' import type { TaggingStyle } from './tagging-style' export type Tagging = LocalMode export type Taggings = Tagging[] export const taggings = ref([]) export const createTagging = (tagging: Partial = {}): Tagging => ({ id: createTemploraryID(), title: ``, styleId: defaultStyle.value?.id || '', desc: '', part: '', method: '', principal: '', images: [], ...tagging }) let bcTaggings: Taggings = [] export const getBackupTaggings = () => bcTaggings export const backupTaggings = () => { bcTaggings = taggings.value.map(tagging => ({ ...tagging, images: [...tagging.images], })) } export const transformTagging = async (tagging: Tagging): Promise => { const images: string[] = [] const uploadImages = tagging.images.map((file, index) => uploadFile(file).then(url => images[index] = url) ) await Promise.all(uploadImages) return { ...tagging, images } } export const recoverTaggings = recoverStoreItems(taggings, () => bcTaggings) export const addTagging = addStoreItem(taggings, async (localTagging) => { const positions = getTaggingPositions(localTagging) const serviceTagging = await postAddTagging(localTagging) for (const position of positions) { position.taggingId = serviceTagging.id } return serviceTagging }, transformTagging) export const deleteTagging = deleteStoreItem(taggings, async tagging => { const positions = getTaggingPositions(tagging) await postDeleteTagging(tagging.id) taggingPositions.value.filter(position => !positions.includes(position)) }) export const updateTagging = updateStoreItem(taggings, postUpdateTagging, transformTagging) export const initialTaggings = fetchStoreItems(taggings, async () => { const taggings = await fetchTaggings() await Promise.all(taggings.map(initTaggingPositionsByTagging)) return taggings }, backupTaggings) export const saveTaggings = saveStoreItems( taggings, getBackupTaggings, { add: addTagging, update: updateTagging, delete: deleteTagging, } ) export const autoSaveTaggings = autoSetModeCallback([taggings, taggingPositions, taggingStyles], { backup: togetherCallback([backupTaggings, backupTaggingPositions, backupTaggingStyles]), recovery: togetherCallback([recoverTaggings, recoverTaggingPositions, recoverTaggingStyles]), save: async () => { const styles = taggings.value.map(tagging => getTaggingStyle(tagging.styleId)) await saveTaggingStyles() for (let i = 0; i < styles.length; i++) { if (styles[i]) { taggings.value[i].styleId = (styles[i] as TaggingStyle).id } } await saveTaggings() await saveTaggingPositions() }, })