sys.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import { ref, computed, watch } from 'vue'
  2. import { asyncBusFactory } from '@/utils'
  3. import { Dialog } from 'bill/index'
  4. import { useViewStack } from '@/hook'
  5. const Flags = {
  6. EDIT: 0b10,
  7. // 已经保存,是最新的
  8. NOW: 0b100,
  9. // 可写模式,用户已登陆
  10. LOGIN: 0b1000,
  11. } as const
  12. const mode = ref<number>(Flags.NOW)
  13. export const isEdit = computed(() => !!(mode.value & Flags.EDIT))
  14. export const isLogin = computed(() => !!(mode.value & Flags.LOGIN))
  15. export const isOld = computed(() => !(mode.value & Flags.NOW))
  16. export const isNow = computed(() => !!(mode.value & Flags.NOW))
  17. export const title = '融合平台'
  18. export const TemploraryID = '-1'
  19. export const sysBus = asyncBusFactory<{ save: void; leave: void }>()
  20. // 进入编辑界面
  21. export const enterEdit = () => {
  22. mode.value |= Flags.EDIT
  23. }
  24. export const enterOld = () => {
  25. mode.value &= ~Flags.NOW
  26. }
  27. // 放弃保存内容
  28. export const giveupSave = () => {
  29. sysBus.off('save')
  30. mode.value |= Flags.NOW
  31. }
  32. // 放弃编辑内容
  33. export const giveupLeave = () => {
  34. giveupSave()
  35. sysBus.off('leave')
  36. mode.value &= ~Flags.EDIT
  37. }
  38. // 保存
  39. export const save = async () => {
  40. await sysBus.emit('save')
  41. giveupSave()
  42. }
  43. // 离开
  44. export const leave = async () => {
  45. if (isOld.value && !(await Dialog.confirm('您有操作未保存,确定要退出吗?'))) {
  46. return;
  47. }
  48. await sysBus.emit('leave')
  49. giveupLeave()
  50. }
  51. export type AutoSetModeSetting<T> = {
  52. save: () => any
  53. leave?: () => any
  54. isUpdate?: (newCurrent: T, oldCurrent: T) => boolean
  55. auto?: boolean
  56. backup?: () => void
  57. recovery?: () => void
  58. }
  59. export const autoSetModeCallback = <T extends object>(current: T, setting: AutoSetModeSetting<T>) => {
  60. let isSave = false
  61. const leaveCallback = (setting.recovery || setting.backup)
  62. && (() => {
  63. setting.recovery && setting.recovery()
  64. setting.backup && setting.backup()
  65. setting.leave && setting.leave()
  66. })
  67. const saveCallback = async () => {
  68. isSave = true
  69. await setting.save()
  70. setting.backup && setting.backup()
  71. isSave = false
  72. }
  73. const handler = (newv: T, oldv: T) => {
  74. if (isSave) return
  75. if (!setting.isUpdate || setting.isUpdate(newv, oldv)) {
  76. isEdit.value || enterEdit()
  77. isOld.value || enterOld()
  78. saveCallback && sysBus.on('save', saveCallback, { pre: true })
  79. }
  80. leaveCallback && sysBus.on('leave', leaveCallback, { pre: true })
  81. }
  82. return () => {
  83. setting.backup && setting.backup()
  84. return watch(current, handler, { deep: true })
  85. }
  86. }
  87. export const useAutoSetMode = <T extends object>(current: T, setting: AutoSetModeSetting<T>) => {
  88. const startWatch = autoSetModeCallback(current, setting)
  89. useViewStack(startWatch)
  90. }