sys.ts 4.1 KB

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