sys.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. console.error(currentMeta.value)
  24. const last = currentMeta.value && 'sysTitle' in currentMeta.value
  25. ? currentMeta.value.sysTitle
  26. : defTitle.value
  27. console.error(prefix.value)
  28. if (prefix.value && last) {
  29. return prefix.value + ' | ' + last
  30. } else {
  31. return prefix.value + last
  32. }
  33. })
  34. watchEffect(() => (document.title = title.value))
  35. let currentTempIndex = 0
  36. export const isTemploraryID = (id: string) => id.includes('__currentTempIndex__')
  37. export const createTemploraryID = () => `__currentTempIndex__${currentTempIndex++}`
  38. export const sysBus = asyncBusFactory<{ save: void; leave: void }>()
  39. // 进入编辑界面
  40. export const enterEdit = (cb?: () => void) => {
  41. mode.value |= Flags.EDIT
  42. cb && sysBus.on('leave', cb)
  43. }
  44. export const enterOld = (cb?: () => void) => {
  45. mode.value &= ~Flags.NOW
  46. cb && sysBus.on('save', cb)
  47. }
  48. // 放弃保存内容
  49. export const giveupSave = () => {
  50. sysBus.off('save')
  51. mode.value |= Flags.NOW
  52. }
  53. // 放弃编辑内容
  54. export const giveupLeave = () => {
  55. giveupSave()
  56. sysBus.off('leave')
  57. mode.value &= ~Flags.EDIT
  58. }
  59. // 保存
  60. export const save = async () => {
  61. await sysBus.emit('save')
  62. giveupSave()
  63. leave()
  64. }
  65. // 离开
  66. export const leave = async () => {
  67. if (isOld.value && !(await Dialog.confirm('您有操作未保存,确定要退出吗?'))) {
  68. return;
  69. }
  70. await sysBus.emit('leave')
  71. giveupLeave()
  72. }
  73. export type AutoSetModeSetting<T> = {
  74. save: () => any
  75. leave?: () => any
  76. isUpdate?: (newCurrent: UnwrapRef<T>, oldCurrent?: UnwrapRef<T>) => boolean
  77. auto?: boolean
  78. backup?: () => void
  79. recovery?: () => void
  80. }
  81. let isUnset = false
  82. export const unSetModelUpdate = (run: () => void) => {
  83. isUnset = true
  84. run()
  85. nextTick(() => isUnset = false)
  86. }
  87. export const autoSetModeCallback = <T extends object>(current: T, setting: AutoSetModeSetting<T>, last = true) => {
  88. let isSave = false
  89. const leaveCallback = (setting.recovery || setting.backup)
  90. && (() => {
  91. setting.recovery && setting.recovery()
  92. setting.backup && setting.backup()
  93. setting.leave && setting.leave()
  94. })
  95. const saveCallback = async () => {
  96. leaveCallback && sysBus.off('leave', leaveCallback, { last })
  97. isSave = true
  98. await setting.save()
  99. setting.backup && setting.backup()
  100. isSave = false
  101. }
  102. const handler = (newv: UnwrapRef<T>, oldv?: UnwrapRef<T>) => {
  103. if (isSave || isUnset) return
  104. if (!setting.isUpdate || setting.isUpdate(newv, oldv)) {
  105. isEdit.value || enterEdit()
  106. isOld.value || enterOld()
  107. saveCallback && sysBus.on('save', saveCallback, { last })
  108. }
  109. leaveCallback && sysBus.on('leave', leaveCallback, { last })
  110. }
  111. return () => {
  112. setting.backup && setting.backup()
  113. return watch(current as UnwrapRef<T>, handler, { deep: true })
  114. }
  115. }
  116. export const useAutoSetMode = <T extends object>(current: T, setting: AutoSetModeSetting<T>, last = true) => {
  117. const startWatch = autoSetModeCallback(current, setting, last)
  118. useViewStack(startWatch)
  119. }