use-group.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { computed, reactive, Ref } from "vue";
  2. import { PropertyDescribes } from "../html-mount/propertys";
  3. import { installGlobalVar } from "./use-global-vars";
  4. import { inRevise, mergeFuns } from "@/utils/shared";
  5. import { useStore } from "../store";
  6. import { ShapeType } from "../components";
  7. import { ui18n } from "@/lang";
  8. export const useGlobalDescribes = installGlobalVar(() => {
  9. const shapesDescribes: Record<string, PropertyDescribes> = reactive({});
  10. const shapesSetCount: Record<string, number> = {};
  11. const data: Record<string, { id: string }> = reactive({});
  12. return {
  13. set(item: { id: string }, descs: PropertyDescribes) {
  14. if (item.id in shapesSetCount) {
  15. shapesSetCount[item.id]++;
  16. } else {
  17. shapesSetCount[item.id] = 1;
  18. }
  19. shapesDescribes[item.id] = descs;
  20. data[item.id] = item;
  21. },
  22. del(id: string) {
  23. if (id in shapesSetCount) {
  24. shapesSetCount[id]--;
  25. }
  26. if (shapesSetCount[id] === 0) {
  27. delete shapesDescribes[id];
  28. delete shapesSetCount[id];
  29. delete data[id];
  30. }
  31. },
  32. get(id: string) {
  33. return (
  34. shapesDescribes[id] && { desc: shapesDescribes[id], data: data[id] }
  35. );
  36. },
  37. };
  38. });
  39. export const useComponentsDescribes = (ids: Ref<string[]>) => {
  40. const gdesc = useGlobalDescribes();
  41. const store = useStore();
  42. const excludeKeys = ["length", "name"];
  43. const groups = computed(() => {
  44. return ids.value
  45. .map((id) => gdesc.get(id))
  46. .filter((item) => !!item)
  47. .map((item) => ({ ...item, type: store.getType(item.data.id) }));
  48. });
  49. const similars = [
  50. ["rectangle", "circle", "triangle", "polygon"],
  51. ] as ShapeType[][];
  52. const shareDescribes = computed(() => {
  53. if (groups.value.length === 0) {
  54. return {};
  55. }
  56. const types = [
  57. ...new Set(groups.value.map((item) => item.type)),
  58. ] as ShapeType[];
  59. if (types.length > 1) {
  60. if (
  61. !similars.some((similar) => types.every((t) => similar.includes(t)))
  62. ) {
  63. return;
  64. }
  65. }
  66. const shareDescribes: Record<
  67. string,
  68. { desc: PropertyDescribes[string][]; data: { id: string }[] }
  69. > = {};
  70. const shareKeys: string[] = Object.keys(groups.value[0].desc);
  71. for (const item of groups.value) {
  72. const keys = Object.keys(item.desc);
  73. for (const key of keys) {
  74. if (shareKeys.includes(key)) {
  75. if (!shareDescribes[key]) {
  76. shareDescribes[key] = { desc: [], data: [] };
  77. } else {
  78. const temp = shareDescribes[key].desc[0];
  79. if (inRevise(temp.props, item.desc[key].props)) {
  80. delete shareDescribes[key];
  81. shareKeys.splice(shareKeys.indexOf(key), 1);
  82. continue;
  83. }
  84. }
  85. shareDescribes[key].desc.push(item.desc[key]);
  86. shareDescribes[key].data.push(item.data);
  87. }
  88. }
  89. for (let i = 0; i < shareKeys.length; i++) {
  90. if (!keys.includes(shareKeys[i])) {
  91. delete shareDescribes[shareKeys[i]];
  92. shareKeys.splice(i--, 1);
  93. }
  94. }
  95. }
  96. return shareDescribes;
  97. });
  98. const stopWatchs: (() => void)[] = [];
  99. const mergeDesc = computed(() => {
  100. mergeFuns(stopWatchs)();
  101. stopWatchs.length = 0;
  102. const mergeDesc: Record<
  103. string,
  104. PropertyDescribes[string] & { joins: { id: string }[] }
  105. > = {};
  106. for (const key in shareDescribes.value) {
  107. if (excludeKeys.includes(key)) continue;
  108. const { desc: descs, data } = shareDescribes.value[key];
  109. mergeDesc[key] = {
  110. ...descs[0],
  111. joins: data,
  112. };
  113. let value = descs[0].value;
  114. let i = 1;
  115. for (; i < descs.length; i++) {
  116. if (descs[i].value !== value) {
  117. break;
  118. }
  119. }
  120. if (i !== descs.length) {
  121. mergeDesc[key].label =
  122. mergeDesc[key].label + `(${ui18n.t("sys.sys.more")})`;
  123. value = undefined;
  124. }
  125. Object.defineProperty(mergeDesc[key], "value", {
  126. get() {
  127. return value;
  128. },
  129. set(val) {
  130. for (const desc of descs) {
  131. desc.value = val;
  132. }
  133. return true;
  134. },
  135. });
  136. delete mergeDesc[key].default;
  137. }
  138. return mergeDesc;
  139. });
  140. return mergeDesc;
  141. };