123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import { ref, computed, watch, nextTick } from 'vue'
- import { asyncBusFactory } from '@/utils'
- import { Dialog } from 'bill/index'
- import { useViewStack } from '@/hook'
- import type { UnwrapRef } from 'vue'
- const Flags = {
- EDIT: 0b10,
- // 已经保存,是最新的
- NOW: 0b100,
- // 可写模式,用户已登陆
- LOGIN: 0b1000,
- } as const
- const mode = ref<number>(Flags.NOW)
- export const isEdit = computed(() => !!(mode.value & Flags.EDIT))
- export const isLogin = computed(() => !!(mode.value & Flags.LOGIN))
- export const isOld = computed(() => !(mode.value & Flags.NOW))
- export const isNow = computed(() => !!(mode.value & Flags.NOW))
- export const title = '多元融合'
- export const appEl = ref<HTMLDivElement | null>(null)
- let currentTempIndex = 0
- export const isTemploraryID = (id: string) => id.includes('__currentTempIndex__')
- export const createTemploraryID = () => `__currentTempIndex__${currentTempIndex++}`
- export const sysBus = asyncBusFactory<{ save: void; leave: void }>()
- // 进入编辑界面
- export const enterEdit = (cb?: () => void) => {
- mode.value |= Flags.EDIT
- cb && sysBus.on('leave', cb)
- }
- export const enterOld = (cb?: () => void) => {
- mode.value &= ~Flags.NOW
- cb && sysBus.on('save', cb)
- }
- // 放弃保存内容
- export const giveupSave = () => {
- sysBus.off('save')
- mode.value |= Flags.NOW
- }
- // 放弃编辑内容
- export const giveupLeave = () => {
- giveupSave()
- sysBus.off('leave')
- mode.value &= ~Flags.EDIT
- }
- // 保存
- export const save = async () => {
- await sysBus.emit('save')
- giveupSave()
- leave()
- }
- // 离开
- export const leave = async () => {
- if (isOld.value && !(await Dialog.confirm('您有操作未保存,确定要退出吗?'))) {
- return;
- }
- await sysBus.emit('leave')
- giveupLeave()
- }
- export type AutoSetModeSetting<T> = {
- save: () => any
- leave?: () => any
- isUpdate?: (newCurrent: UnwrapRef<T>, oldCurrent?: UnwrapRef<T>) => boolean
- auto?: boolean
- backup?: () => void
- recovery?: () => void
- }
- let isUnset = false
- export const unSetModelUpdate = (run: () => void) => {
- console.error('unset')
- isUnset = true
- run()
- nextTick(() => isUnset = false)
- }
- export const autoSetModeCallback = <T extends object>(current: T, setting: AutoSetModeSetting<T>) => {
- let isSave = false
- const leaveCallback = (setting.recovery || setting.backup)
- && (() => {
- setting.recovery && setting.recovery()
- setting.backup && setting.backup()
- setting.leave && setting.leave()
- })
-
- const saveCallback = async () => {
- leaveCallback && sysBus.off('leave', leaveCallback, { last: true })
- isSave = true
- await setting.save()
- setting.backup && setting.backup()
- isSave = false
- }
- const handler = (newv: UnwrapRef<T>, oldv?: UnwrapRef<T>) => {
- if (isSave || isUnset) return
- if (!setting.isUpdate || setting.isUpdate(newv, oldv)) {
- isEdit.value || enterEdit()
- isOld.value || enterOld()
- saveCallback && sysBus.on('save', saveCallback, { last: true })
- }
- leaveCallback && sysBus.on('leave', leaveCallback, { last: true })
- }
- return () => {
- setting.backup && setting.backup()
- return watch(current as UnwrapRef<T>, handler, { deep: true })
- }
- }
- export const useAutoSetMode = <T extends object>(current: T, setting: AutoSetModeSetting<T>) => {
- const startWatch = autoSetModeCallback(current, setting)
- useViewStack(startWatch)
- }
|