DataAnnotation.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. type Constructor<T = unknown> = new (...args: any[]) => T
  2. type DefaultType = number | string | boolean | (() => Record<string, any>) | (() => Array<any>) | (() => Map<any, any>) | (() => Set<any>)|(() => number);
  3. type NotNullableDefaultType = Exclude<DefaultType, null | undefined | Constructor | (() => Constructor)>;
  4. interface PropType {
  5. // 属性值
  6. defaultValue: any
  7. // 序列号化名
  8. serializeName: string
  9. // 属性的构造器
  10. constructor: Constructor
  11. }
  12. type PropTypes = Map<string, PropType>
  13. /**
  14. * 不要赋值空字段,这里需要通过值判断类型,不支持,map,set,array和该注解的嵌套
  15. * @param type 需要保存字段的类型
  16. * @param defaultValue 需要保存字段的默认值
  17. * @returns
  18. */
  19. function saveProp(defaultValue: NotNullableDefaultType, serializeName?: string) {
  20. let res: PropertyDecorator = function (target: Object, prop: string) {
  21. let myConstructor = target.constructor as Constructor
  22. let valueMap = DataAnnotation.instance.propData.get(myConstructor)
  23. if (!valueMap) {
  24. valueMap = new Map
  25. DataAnnotation.instance.propData.set(myConstructor, valueMap)
  26. }
  27. if (defaultValue == undefined || defaultValue == null) {
  28. // 这里出现异常
  29. throw new Error("未赋默认值")
  30. }
  31. serializeName = serializeName ?? prop
  32. // 获取默认属性,不然每次序列化都需要实例化
  33. let defaultConstructor = null
  34. valueMap.set(prop, { defaultValue: defaultValue, serializeName: serializeName, constructor: defaultConstructor })
  35. }
  36. return res
  37. }
  38. /**
  39. *
  40. * @param component 存储的根模块,如果不填,就默认为不是模块,和saveCompoent效果一样
  41. * @param customize 用户是否自定义序列户方法,一旦启动,则用户需要自己实现unserialize和serialize方法
  42. * @returns
  43. */
  44. function saveRoot(componentName?: string, customize?: boolean) {
  45. return function (target: Constructor) {
  46. if (!componentName || componentName == "") {
  47. DataAnnotation.instance.saveCompoentSet.add(target)
  48. return
  49. }
  50. // 首字母小写注入
  51. if (DataAnnotation.instance.root.get(componentName)) {
  52. // 这里出现异常
  53. throw new Error("模块重复注入")
  54. }
  55. DataAnnotation.instance.root.set(componentName, target)
  56. DataAnnotation.instance.reregistMap.set(target, componentName)
  57. }
  58. }
  59. /**
  60. * 开启这个注解的类,会拥有序列化方法
  61. * @returns
  62. */
  63. function saveCompoent() {
  64. return function (target: Constructor) {
  65. // 首字母小写注入
  66. DataAnnotation.instance.saveCompoentSet.add(target)
  67. }
  68. }
  69. /**
  70. * 存放注解相关内容
  71. */
  72. class DataAnnotation {
  73. /** 私有构造函数 */
  74. private constructor() { }
  75. private static _instance: DataAnnotation
  76. /** 单例模式 */
  77. public static get instance(): DataAnnotation {
  78. if (!this._instance) {
  79. this._instance = new this
  80. }
  81. return this._instance
  82. };
  83. reregistMap: Map<Constructor, string> = new Map
  84. root: Map<string, Constructor> = new Map
  85. propData: Map<Constructor, PropTypes> = new Map<Constructor, PropTypes>
  86. saveCompoentSet: Set<Constructor> = new Set
  87. }
  88. /**
  89. * 全局的数据保存接口
  90. */
  91. export abstract class GlobalSaveData {
  92. constructor() {
  93. if (!GlobalSaveData.init) {
  94. this.initProp()
  95. }
  96. }
  97. private static init = false
  98. private initProp() {
  99. GlobalSaveData.init = true
  100. this.getClassMap().forEach(v => {
  101. let map = this.getPropMap().get(v)
  102. if (map) {
  103. map.forEach((v) => {
  104. let defaultValue = null
  105. if (typeof v.defaultValue == 'function') {
  106. defaultValue = v.defaultValue()
  107. } else {
  108. defaultValue = v.defaultValue
  109. }
  110. v.constructor = defaultValue?.constructor
  111. })
  112. }
  113. })
  114. }
  115. /**
  116. * saveRoot注册的类
  117. */
  118. getClassMap(): Map<string, Constructor> {
  119. return DataAnnotation.instance.root;
  120. }
  121. /**
  122. * saveData注册的变量
  123. * @returns Constructor 函数构造器
  124. */
  125. getPropMap(): Map<Constructor, PropTypes> {
  126. return DataAnnotation.instance.propData;
  127. }
  128. getCompoentSet(): Set<Constructor> {
  129. return DataAnnotation.instance.saveCompoentSet;
  130. }
  131. /**
  132. *
  133. * @param key 需要反序列化的构造器
  134. * @param saveData 需要反序列化的类
  135. */
  136. abstract unserialize<T>(key: Constructor<T>, saveData: any): T
  137. abstract serialize<T>(data: T, key?: Constructor<T>): Object;
  138. /**
  139. * 判断还类是不是注解类
  140. */
  141. isCompoent(compoent: Constructor): boolean {
  142. return this.getCompoentSet().has(compoent) || DataAnnotation.instance.reregistMap.has(compoent)
  143. }
  144. /**
  145. * 通过注册的类名获取描述信息
  146. * @param compoent 模块类
  147. */
  148. getNameByConstructor(compoent: Constructor): string {
  149. return DataAnnotation.instance.reregistMap.get(compoent)
  150. }
  151. }
  152. // 继承接口的写法,应对比较复杂的类
  153. abstract class SaveInterface {
  154. // 标记是不是一个类的方法
  155. private static spuerTop = SaveInterface
  156. abstract serialize(): any;
  157. abstract unserialize(data: any): SaveInterface;
  158. }
  159. export {
  160. saveProp,
  161. saveRoot,
  162. // saveCompoent,
  163. SaveInterface
  164. }
  165. export type { PropTypes };