sys.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { ref, computed, watch, nextTick, watchEffect } from 'vue'
  2. import { asyncBusFactory } from '@/utils'
  3. import { Dialog } from 'bill/index'
  4. import { useViewStack } from '@/hook'
  5. import type { UnwrapRef } from 'vue'
  6. import { currentMeta } from '@/router'
  7. const Flags = {
  8. EDIT: 0b10,
  9. // 已经保存,是最新的
  10. NOW: 0b100,
  11. // 可写模式,用户已登陆
  12. LOGIN: 0b1000,
  13. } as const
  14. const mode = ref<number>(Flags.NOW)
  15. export const isEdit = computed(() => !!(mode.value & Flags.EDIT))
  16. export const isLogin = computed(() => !!(mode.value & Flags.LOGIN))
  17. export const isOld = computed(() => !(mode.value & Flags.NOW))
  18. export const isNow = computed(() => !!(mode.value & Flags.NOW))
  19. export const appEl = ref<HTMLDivElement | null>(null)
  20. export const prefix = ref('')
  21. export const defTitle = ref('案件信息')
  22. export const title = computed(() => {
  23. const last = currentMeta.value && 'sysTitle' in currentMeta.value
  24. ? currentMeta.value.sysTitle
  25. : defTitle.value
  26. if (prefix.value && last) {
  27. return prefix.value + ' | ' + last
  28. } else {
  29. return prefix.value + last
  30. }
  31. })
  32. watchEffect(() => (document.title = title.value))
  33. let currentTempIndex = 0
  34. export const isTemploraryID = (id: string) => id.includes('__currentTempIndex__')
  35. export const createTemploraryID = () => `__currentTempIndex__${currentTempIndex++}`
  36. export const sysBus = asyncBusFactory<{ save: void; leave: void }>()
  37. // 进入编辑界面
  38. export const enterEdit = (cb?: () => void) => {
  39. mode.value |= Flags.EDIT
  40. cb && sysBus.on('leave', cb)
  41. }
  42. export const enterOld = (cb?: () => void) => {
  43. mode.value &= ~Flags.NOW
  44. cb && sysBus.on('save', cb)
  45. }
  46. // 放弃保存内容
  47. export const giveupSave = () => {
  48. sysBus.off('save')
  49. mode.value |= Flags.NOW
  50. }
  51. // 放弃编辑内容
  52. export const giveupLeave = () => {
  53. giveupSave()
  54. sysBus.off('leave')
  55. mode.value &= ~Flags.EDIT
  56. }
  57. // 保存
  58. export const save = async () => {
  59. await sysBus.emit('save')
  60. giveupSave()
  61. leave()
  62. }
  63. // 离开
  64. export const leave = async () => {
  65. if (isOld.value && !(await Dialog.confirm('您有操作未保存,确定要退出吗?'))) {
  66. return;
  67. }
  68. await sysBus.emit('leave')
  69. giveupLeave()
  70. }
  71. export type AutoSetModeSetting<T> = {
  72. save: () => any
  73. leave?: () => any
  74. isUpdate?: (newCurrent: UnwrapRef<T>, oldCurrent?: UnwrapRef<T>) => boolean
  75. auto?: boolean
  76. backup?: () => void
  77. recovery?: () => void
  78. }
  79. let isUnset = false
  80. export const unSetModelUpdate = (run: () => void) => {
  81. isUnset = true
  82. run()
  83. nextTick(() => isUnset = false)
  84. }
  85. export const autoSetModeCallback = <T extends object>(current: T, setting: AutoSetModeSetting<T>, last = true) => {
  86. let isSave = false
  87. const leaveCallback = (setting.recovery || setting.backup)
  88. && (() => {
  89. setting.recovery && setting.recovery()
  90. setting.backup && setting.backup()
  91. setting.leave && setting.leave()
  92. })
  93. const saveCallback = async () => {
  94. leaveCallback && sysBus.off('leave', leaveCallback, { last })
  95. isSave = true
  96. await setting.save()
  97. setting.backup && setting.backup()
  98. isSave = false
  99. }
  100. const handler = (newv: UnwrapRef<T>, oldv?: UnwrapRef<T>) => {
  101. if (isSave || isUnset) return
  102. if (!setting.isUpdate || setting.isUpdate(newv, oldv)) {
  103. isEdit.value || enterEdit()
  104. isOld.value || enterOld()
  105. saveCallback && sysBus.on('save', saveCallback, { last })
  106. }
  107. leaveCallback && sysBus.on('leave', leaveCallback, { last })
  108. }
  109. return () => {
  110. setting.backup && setting.backup()
  111. return watch(current as UnwrapRef<T>, handler, { deep: true })
  112. }
  113. }
  114. export const useAutoSetMode = <T extends object>(current: T, setting: AutoSetModeSetting<T>, last = true) => {
  115. const startWatch = autoSetModeCallback(current, setting, last)
  116. useViewStack(startWatch)
  117. }