fast-crud-ui3 1.5.15-beta2 → 1.5.16-tsc-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/lib/assets/fonts/iconfont.d.ts +0 -0
  2. package/lib/components/checkbox-group/index.d.ts +2 -0
  3. package/lib/components/checkbox-group/src/fast-checkbox-group.d.ts +72 -0
  4. package/lib/components/content-dialog/index.d.ts +2 -0
  5. package/lib/components/content-dialog/src/fast-cell-content.d.ts +83 -0
  6. package/lib/components/json-viewer/index.d.ts +2 -0
  7. package/lib/components/json-viewer/src/fast-json-viewer.d.ts +48 -0
  8. package/lib/components/mapping.d.ts +5 -0
  9. package/lib/components/object-picker/index.d.ts +2 -0
  10. package/lib/components/object-picker/src/fast-object-picker.d.ts +132 -0
  11. package/lib/components/select/index.d.ts +2 -0
  12. package/lib/components/select/src/fast-select.d.ts +83 -0
  13. package/lib/components/table/index.d.ts +2 -0
  14. package/lib/components/table/src/RowConfirm.d.ts +39 -0
  15. package/lib/components/table/src/dynamic-filter-form.d.ts +118 -0
  16. package/lib/components/table/src/dynamic-filter-list.d.ts +57 -0
  17. package/lib/components/table/src/easy-filter.d.ts +118 -0
  18. package/lib/components/table/src/export-confirm.d.ts +12 -0
  19. package/lib/components/table/src/quick-filter-form.d.ts +42 -0
  20. package/lib/components/table/src/row-form.d.ts +33 -0
  21. package/lib/components/table/src/stored-filter-manager.d.ts +55 -0
  22. package/lib/components/table/src/stored-filter.d.ts +37 -0
  23. package/lib/components/table/src/table-head-cell.d.ts +9 -0
  24. package/lib/components/table/src/table.d.ts +507 -0
  25. package/lib/components/table/src/util.d.ts +77 -0
  26. package/lib/components/table-column/config.d.ts +5 -0
  27. package/lib/components/table-column/index.d.ts +2 -0
  28. package/lib/components/table-column/src/table-column.d.ts +256 -0
  29. package/lib/components/table-column-date-picker/config.d.ts +5 -0
  30. package/lib/components/table-column-date-picker/index.d.ts +2 -0
  31. package/lib/components/table-column-date-picker/src/table-column-date-picker.d.ts +173 -0
  32. package/lib/components/table-column-file/config.d.ts +5 -0
  33. package/lib/components/table-column-file/index.d.ts +2 -0
  34. package/lib/components/table-column-file/src/table-column-file.d.ts +285 -0
  35. package/lib/components/table-column-img/config.d.ts +5 -0
  36. package/lib/components/table-column-img/index.d.ts +2 -0
  37. package/lib/components/table-column-img/src/table-column-img.d.ts +285 -0
  38. package/lib/components/table-column-input/config.d.ts +5 -0
  39. package/lib/components/table-column-input/index.d.ts +2 -0
  40. package/lib/components/table-column-input/src/table-column-input.d.ts +173 -0
  41. package/lib/components/table-column-number/config.d.ts +5 -0
  42. package/lib/components/table-column-number/index.d.ts +2 -0
  43. package/lib/components/table-column-number/src/table-column-number.d.ts +173 -0
  44. package/lib/components/table-column-object/config.d.ts +5 -0
  45. package/lib/components/table-column-object/index.d.ts +2 -0
  46. package/lib/components/table-column-object/src/table-column-object.d.ts +315 -0
  47. package/lib/components/table-column-select/config.d.ts +5 -0
  48. package/lib/components/table-column-select/index.d.ts +2 -0
  49. package/lib/components/table-column-select/src/table-column-select.d.ts +276 -0
  50. package/lib/components/table-column-switch/config.d.ts +5 -0
  51. package/lib/components/table-column-switch/index.d.ts +2 -0
  52. package/lib/components/table-column-switch/src/table-column-switch.d.ts +175 -0
  53. package/lib/components/table-column-textarea/config.d.ts +5 -0
  54. package/lib/components/table-column-textarea/index.d.ts +2 -0
  55. package/lib/components/table-column-textarea/src/table-column-textarea.d.ts +173 -0
  56. package/lib/components/table-column-time-picker/config.d.ts +5 -0
  57. package/lib/components/table-column-time-picker/index.d.ts +2 -0
  58. package/lib/components/table-column-time-picker/src/table-column-time-picker.d.ts +173 -0
  59. package/lib/components/upload/index.d.ts +2 -0
  60. package/lib/components/upload/src/fast-upload.d.ts +120 -0
  61. package/lib/fast-crud-ui3.cjs.js +7 -7
  62. package/lib/fast-crud-ui3.es.js +1497 -1152
  63. package/lib/fast-crud-ui3.umd.js +7 -7
  64. package/lib/global.d.ts +42 -0
  65. package/lib/index.d.ts +56 -0
  66. package/lib/mixins/table-column.d.ts +104 -0
  67. package/lib/mixins/upload.d.ts +15 -0
  68. package/lib/model/cond.d.ts +48 -0
  69. package/lib/model/editComponentConfig.d.ts +25 -0
  70. package/lib/model/fastTableOption.d.ts +510 -0
  71. package/lib/model/filterComponentConfig.d.ts +57 -0
  72. package/lib/model/opt.d.ts +20 -0
  73. package/lib/model/order.d.ts +28 -0
  74. package/lib/model/pageQuery.d.ts +43 -0
  75. package/lib/model/query.d.ts +101 -0
  76. package/lib/model/rel.d.ts +5 -0
  77. package/lib/style.css +1 -1
  78. package/lib/util/cache.d.ts +17 -0
  79. package/lib/util/dialog.d.ts +49 -0
  80. package/lib/util/escape.d.ts +7 -0
  81. package/lib/util/http.d.ts +8 -0
  82. package/lib/util/pick.d.ts +9 -0
  83. package/lib/util/util.d.ts +311 -0
  84. package/package.json +19 -5
  85. package/packages/assets/fonts/iconfont.css +163 -0
  86. package/packages/assets/fonts/iconfont.js +1 -0
  87. package/packages/assets/fonts/iconfont.ttf +0 -0
  88. package/packages/assets/fonts/iconfont.woff +0 -0
  89. package/packages/assets/fonts/iconfont.woff2 +0 -0
  90. package/packages/components/checkbox-group/index.js +7 -0
  91. package/packages/components/checkbox-group/src/fast-checkbox-group.vue +83 -0
  92. package/packages/components/content-dialog/index.js +7 -0
  93. package/packages/components/content-dialog/src/fast-cell-content.vue +115 -0
  94. package/packages/components/json-viewer/index.js +7 -0
  95. package/packages/components/json-viewer/src/fast-json-viewer.vue +54 -0
  96. package/packages/components/mapping.js +95 -0
  97. package/packages/components/object-picker/index.js +7 -0
  98. package/packages/components/object-picker/src/fast-object-picker.vue +170 -0
  99. package/packages/components/select/index.js +7 -0
  100. package/packages/components/select/src/fast-select.vue +89 -0
  101. package/packages/components/table/index.js +7 -0
  102. package/packages/components/table/src/RowConfirm.vue +87 -0
  103. package/packages/components/table/src/dynamic-filter-form.vue +253 -0
  104. package/packages/components/table/src/dynamic-filter-list.vue +172 -0
  105. package/packages/components/table/src/easy-filter.vue +129 -0
  106. package/packages/components/table/src/export-confirm.vue +55 -0
  107. package/packages/components/table/src/quick-filter-form.vue +140 -0
  108. package/packages/components/table/src/row-form.vue +137 -0
  109. package/packages/components/table/src/stored-filter-manager.vue +240 -0
  110. package/packages/components/table/src/stored-filter.vue +180 -0
  111. package/packages/components/table/src/table-head-cell.vue +41 -0
  112. package/packages/components/table/src/table.vue +1309 -0
  113. package/packages/components/table/src/util.js +496 -0
  114. package/packages/components/table-column/config.js +64 -0
  115. package/packages/components/table-column/index.js +7 -0
  116. package/packages/components/table-column/src/table-column.vue +44 -0
  117. package/packages/components/table-column-date-picker/config.js +139 -0
  118. package/packages/components/table-column-date-picker/index.js +7 -0
  119. package/packages/components/table-column-date-picker/src/table-column-date-picker.vue +54 -0
  120. package/packages/components/table-column-file/config.js +83 -0
  121. package/packages/components/table-column-file/index.js +7 -0
  122. package/packages/components/table-column-file/src/table-column-file.vue +79 -0
  123. package/packages/components/table-column-img/config.js +83 -0
  124. package/packages/components/table-column-img/index.js +7 -0
  125. package/packages/components/table-column-img/src/table-column-img.vue +82 -0
  126. package/packages/components/table-column-input/config.js +77 -0
  127. package/packages/components/table-column-input/index.js +7 -0
  128. package/packages/components/table-column-input/src/table-column-input.vue +60 -0
  129. package/packages/components/table-column-number/config.js +89 -0
  130. package/packages/components/table-column-number/index.js +7 -0
  131. package/packages/components/table-column-number/src/table-column-number.vue +54 -0
  132. package/packages/components/table-column-object/config.js +66 -0
  133. package/packages/components/table-column-object/index.js +7 -0
  134. package/packages/components/table-column-object/src/table-column-object.vue +75 -0
  135. package/packages/components/table-column-select/config.js +66 -0
  136. package/packages/components/table-column-select/index.js +7 -0
  137. package/packages/components/table-column-select/src/table-column-select.vue +101 -0
  138. package/packages/components/table-column-switch/config.js +55 -0
  139. package/packages/components/table-column-switch/index.js +7 -0
  140. package/packages/components/table-column-switch/src/table-column-switch.vue +82 -0
  141. package/packages/components/table-column-textarea/config.js +77 -0
  142. package/packages/components/table-column-textarea/index.js +7 -0
  143. package/packages/components/table-column-textarea/src/table-column-textarea.vue +56 -0
  144. package/packages/components/table-column-time-picker/config.js +62 -0
  145. package/packages/components/table-column-time-picker/index.js +7 -0
  146. package/packages/components/table-column-time-picker/src/table-column-time-picker.vue +53 -0
  147. package/packages/components/upload/index.js +7 -0
  148. package/packages/components/upload/src/fast-upload.vue +272 -0
  149. package/packages/global.d.ts +42 -0
  150. package/packages/index.js +145 -0
  151. package/packages/mixins/table-column.js +133 -0
  152. package/packages/mixins/upload.js +14 -0
  153. package/packages/model/cond.js +74 -0
  154. package/packages/model/editComponentConfig.js +72 -0
  155. package/packages/model/fastTableOption.js +761 -0
  156. package/packages/model/filterComponentConfig.js +185 -0
  157. package/packages/model/opt.js +21 -0
  158. package/packages/model/order.js +37 -0
  159. package/packages/model/pageQuery.js +52 -0
  160. package/packages/model/query.js +161 -0
  161. package/packages/model/rel.js +5 -0
  162. package/packages/style.scss +5 -0
  163. package/packages/util/cache.js +92 -0
  164. package/packages/util/dialog.js +133 -0
  165. package/packages/util/escape.js +34 -0
  166. package/packages/util/http.js +18 -0
  167. package/packages/util/pick.js +92 -0
  168. package/packages/util/util.js +892 -0
@@ -0,0 +1,185 @@
1
+ import {isUndefined} from "../util/util.js"
2
+ import {escapeValToLabel} from "../util/escape.js"
3
+ import Cond from './cond.js'
4
+ import Opt from './opt.js'
5
+
6
+ /**
7
+ * 筛选组件配置
8
+ */
9
+ class FilterComponentConfig {
10
+ component; // 渲染组件
11
+ col; // 字段名
12
+ opt; // 操作符
13
+ val; // 值
14
+ label; // 显示中文名
15
+ props; // 组件对应的props
16
+ defaultVal; // 默认值
17
+ disabled; // 是否禁用: 表示该筛选项是否可用
18
+ type; // quick, easy, dynamic
19
+ condMapFn = (cond) => [cond];
20
+ index = 99; // 排序
21
+ condMsg = ''; // 条件文本描述
22
+
23
+ /**
24
+ * 构造函数
25
+ * @param component 组件
26
+ * @param col 字段名
27
+ * @param opt 操作符
28
+ * @param val 值
29
+ * @param label 中文名
30
+ * @param props 组件对应的props
31
+ * @param condMapFn 条件获取过滤函数
32
+ */
33
+ constructor({
34
+ component,
35
+ col,
36
+ opt = Opt.LIKE,
37
+ val,
38
+ label,
39
+ props,
40
+ condMapFn = (cond) => [cond],
41
+ type
42
+ }) {
43
+ this.component = component;
44
+ this.col = col;
45
+ this.opt = opt;
46
+ this.label = label;
47
+ this.condMsg = `${label} ${opt}`
48
+ const {disabled, ...validProps} = props; // 移除props中的disabled属性,disabled属性对查询时无效
49
+ this.props = validProps;
50
+ if (!isUndefined(condMapFn)) {
51
+ this.condMapFn = condMapFn;
52
+ }
53
+
54
+ this.defaultVal = val;
55
+ this.disabled = false;
56
+ this.type = type;
57
+ this.val = val;
58
+ }
59
+
60
+ /**
61
+ * 值为默认值
62
+ */
63
+ isDefaultVal() {
64
+ return this.val === this.defaultVal
65
+ }
66
+
67
+ /**
68
+ * 此筛选项是否有效
69
+ * @returns {boolean}
70
+ */
71
+ isEffective() {
72
+ if (this.opt === Opt.NULL || this.opt === Opt.NNULL || this.opt === Opt.EMPTY || this.opt === Opt.NEMPTY) {
73
+ return true;
74
+ }
75
+ return this.val !== null && this.val !== undefined && this.val !== '' && this.val.length !== 0;
76
+ }
77
+
78
+ /**
79
+ * 返回值是否变更
80
+ * @return {boolean}
81
+ */
82
+ reset() {
83
+ const valChanged = (this.val !== this.defaultVal)
84
+ this.val = this.defaultVal
85
+ return valChanged
86
+ }
87
+
88
+ getConds() {
89
+ if (this.opt === Opt.NULL || this.opt === Opt.NNULL || this.opt === Opt.EMPTY || this.opt === Opt.NEMPTY) {
90
+ return [new Cond(this.col, this.opt, null)]
91
+ }
92
+ return this.condMapFn(new Cond(this.col, this.opt, this.val));
93
+ }
94
+
95
+ /**
96
+ * 更新条件的文本描述, 例如用于回显在dynamic-filter-list上
97
+ */
98
+ updateCondMsg() {
99
+ return new Promise((resolve, reject) => {
100
+ const component = this.component
101
+ const label = this.label
102
+ const props = this.props
103
+ if (!this.isEffective()) {
104
+ this.disabled = true
105
+ this.condMsg = `[${label}]无有效值`
106
+ resolve()
107
+ return
108
+ }
109
+ const conds = this.getConds();
110
+ const allPromises = []
111
+ for (let i = 0; i < conds.length; i++) {
112
+ let {opt, val} = conds[i];
113
+ const promise = new Promise((resolve, reject) => {
114
+ let text
115
+ escapeValToLabel(component, val, props).then(showVal => {
116
+ switch (opt) {
117
+ case Opt.EQ:
118
+ case Opt.NE:
119
+ case Opt.GT:
120
+ case Opt.GE:
121
+ case Opt.LT:
122
+ case Opt.LE:
123
+ text = `${label} ${opt} ${showVal}`;
124
+ break;
125
+ case Opt.LIKE:
126
+ text = `${label} 包含'${showVal}'`;
127
+ break;
128
+ case Opt.LLIKE:
129
+ text = `${label}以'${showVal}'结尾`
130
+ break;
131
+ case Opt.RLIKE:
132
+ text = `${label}以'${showVal}'打头`
133
+ break;
134
+ case Opt.NLIKE:
135
+ text = `${label} 不包含'${showVal}'`;
136
+ break;
137
+ case Opt.IN:
138
+ text = `${label} 包含 ${showVal}`;
139
+ break;
140
+ case Opt.NIN:
141
+ text = `${label} 不包含 ${showVal}`;
142
+ break;
143
+ case Opt.NULL:
144
+ text = `${label} 为null`;
145
+ break;
146
+ case Opt.NNULL:
147
+ text = `${label} 不为null`;
148
+ break;
149
+ case Opt.EMPTY:
150
+ text = `${label} 为空`;
151
+ break;
152
+ case Opt.NEMPTY:
153
+ text = `${label} 不为空`;
154
+ break;
155
+ case Opt.BTW:
156
+ text = `${label} 在${showVal}之间`;
157
+ break;
158
+ default:
159
+ text = `${label}未知的比较符`
160
+ break
161
+ }
162
+ resolve(text)
163
+ }).catch(err => {
164
+ console.error(err)
165
+ resolve(`${label} ${opt} ${val}`)
166
+ })
167
+ })
168
+ allPromises.push(promise)
169
+ }
170
+ Promise.all(allPromises).then(texts => {
171
+ let condMsg = '';
172
+ for (let i = 0; i < texts.length; i++) {
173
+ condMsg += texts[i]
174
+ if (i !== texts.length - 1) {
175
+ condMsg += " 且 "
176
+ }
177
+ }
178
+ this.condMsg = condMsg
179
+ resolve()
180
+ })
181
+ })
182
+ }
183
+ }
184
+
185
+ export default FilterComponentConfig
@@ -0,0 +1,21 @@
1
+ const Opt = Object.freeze({
2
+ EQ: "=",
3
+ NE: "!=",
4
+ GT: ">",
5
+ GE: ">=",
6
+ LT: "<",
7
+ LE: "<=",
8
+ IN: "in",
9
+ NIN: "nin",
10
+ LIKE: "like",
11
+ LLIKE: "llike",
12
+ RLIKE: "rlike",
13
+ NLIKE: "nlike",
14
+ NULL: "null",
15
+ NNULL: "nnull",
16
+ EMPTY: "empty",
17
+ NEMPTY: "nempty",
18
+ BTW: "between",
19
+ })
20
+
21
+ export default Opt
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 排序对象
3
+ */
4
+ class Order {
5
+ /**
6
+ * 排序字段(英文字段),需要和后端分页响应的字段名对应
7
+ * @type {string}
8
+ */
9
+ col;
10
+ /**
11
+ * 是否升序
12
+ * @type {boolean}
13
+ */
14
+ asc;
15
+
16
+ /**
17
+ * 构造器
18
+ * @param col 排序字段
19
+ * @param asc 是否升序,默认false,即降序
20
+ */
21
+ constructor(col, asc = false) {
22
+ this.col = col;
23
+ this.asc = asc;
24
+ }
25
+
26
+ /**
27
+ * 设置是否升序
28
+ * @param asc
29
+ * @return {Order}
30
+ */
31
+ setAsc(asc) {
32
+ this.asc = asc;
33
+ return this;
34
+ }
35
+ }
36
+
37
+ export default Order
@@ -0,0 +1,52 @@
1
+ import Query from "./query.js";
2
+
3
+ /**
4
+ * 分页请求参数模型
5
+ */
6
+ class PageQuery extends Query {
7
+ /**
8
+ * 当前页,默认1
9
+ * @type {number}
10
+ */
11
+ current = 1;
12
+ /**
13
+ * 每页条数,默认20条
14
+ * @type {number}
15
+ */
16
+ size = 20;
17
+
18
+ /**
19
+ * 构造器
20
+ * @param current 当前页(默认1)
21
+ * @param size 每页条数(默认20)
22
+ */
23
+ constructor(current = 1, size = 20) {
24
+ super();
25
+ this.current = current;
26
+ this.size = size;
27
+ }
28
+
29
+ /**
30
+ * 设置每页大小
31
+ * @param size
32
+ */
33
+ setSize(size) {
34
+ this.size = size;
35
+ return this;
36
+ }
37
+
38
+ /**
39
+ * 将当前对象转为json
40
+ * @return {{current: number, size: number, conds: *, extra: {[p: string]: null|*}, distinct: *, orders: *, cols: *}}
41
+ */
42
+ toJson() {
43
+ const json = super.toJson();
44
+ return {
45
+ ...json,
46
+ current: this.current,
47
+ size: this.size
48
+ }
49
+ }
50
+ }
51
+
52
+ export default PageQuery
@@ -0,0 +1,161 @@
1
+ import {caseToCamel, isBoolean, isEmpty} from "../util/util.js"
2
+ import Cond from './cond.js'
3
+ import Order from './order.js'
4
+
5
+ /**
6
+ * 请求参数模型
7
+ */
8
+ class Query {
9
+ /**
10
+ * 请求的字段列表。若为空,则表示请求所有字段。字段必须是分页请求返回的字段(且对应数据表字段)
11
+ * @type {[]}
12
+ */
13
+ cols = [];
14
+ /**
15
+ * 查询条件
16
+ * @type {Cond[]}
17
+ */
18
+ conds = [];
19
+ /**
20
+ * 是否distinct去重。默认false
21
+ * @type {boolean}
22
+ */
23
+ distinct = false;
24
+ /**
25
+ * 排序数组
26
+ * @type {Order[]}
27
+ */
28
+ orders = [];
29
+ /**
30
+ * 扩展字段
31
+ * @type {{}}
32
+ */
33
+ extra = {};
34
+
35
+ constructor() {
36
+ }
37
+
38
+ /**
39
+ * 设置查询字段数组
40
+ * @param cols {string[]} 字段必须是分页请求返回的字段(且对应数据表字段)
41
+ * @return {Query} 返回当前对象
42
+ */
43
+ setCols(cols) {
44
+ this.cols = cols;
45
+ return this;
46
+ }
47
+
48
+ /**
49
+ * 添加筛选条件
50
+ * @param cond {Cond} 筛选条件
51
+ * @param repeatable {boolean} 是否允许重复的col, 默认true, 即若多次添加相同col的条件, 只会保留最新的
52
+ * @return {Query} 返回当前对象
53
+ */
54
+ addCond(cond, repeatable = true) {
55
+ if (repeatable === false) {
56
+ this.removeCond(c.col)
57
+ }
58
+ this.conds.push(cond);
59
+ return this;
60
+ }
61
+
62
+ /**
63
+ * 按照字段移除已有条件。此字段所有条件都会被移除
64
+ * @param col {string} 字段名
65
+ * @return {Query} 返回当前对象
66
+ */
67
+ removeCond(col) {
68
+ this.conds = this.conds.filter(cond => cond.col !== col);
69
+ return this;
70
+ }
71
+
72
+ /**
73
+ * 设置条件。会覆盖已有条件!
74
+ * @param conds {Array[Cond]} 条件数组
75
+ * @return {Query} 返回当前对象
76
+ */
77
+ setConds(conds) {
78
+ this.conds = conds;
79
+ return this;
80
+ }
81
+
82
+ /**
83
+ * 获取指定字段的所有条件
84
+ * @param col {string}
85
+ * @return {Cond[]}
86
+ */
87
+ getConds(col) {
88
+ return this.conds.filter(cond => cond.col === col);
89
+ }
90
+
91
+ /**
92
+ * 设置distinct去重
93
+ * @return {Query} 返回当前对象
94
+ */
95
+ setDistinct() {
96
+ this.distinct = true;
97
+ return this;
98
+ }
99
+
100
+ /**
101
+ * 添加排序规则
102
+ * @param col {string} 字段名
103
+ * @param asc {boolean} 是否升序
104
+ * @return {Query} 返回当前对象
105
+ */
106
+ addOrder(col, asc) {
107
+ if (isEmpty(col) || !isBoolean(asc)) {
108
+ return this;
109
+ }
110
+ this.removeOrder(col)
111
+ this.orders.push(new Order(col, asc));
112
+ return this;
113
+ }
114
+
115
+ /**
116
+ * 移除排序规则
117
+ * @param col {string} 字段名
118
+ * @return {Query} 返回当前对象
119
+ */
120
+ removeOrder(col) {
121
+ const idx = this.orders.findIndex(o => o.col === col);
122
+ if (idx > -1) {
123
+ this.orders.splice(idx, 1)
124
+ }
125
+ return this;
126
+ }
127
+
128
+ /**
129
+ * 获取排序规则
130
+ * @param col {string}
131
+ * @return {Order} 可能为undefined
132
+ */
133
+ getOrder(col) {
134
+ return this.orders.find(order => order.col === col);
135
+ }
136
+
137
+ /**
138
+ * 将当前查询实例转换为json
139
+ * @return {{conds: Cond[], extra: {[p: string]: null|*}, distinct: boolean, orders: Order[], cols: (*)[]}}
140
+ */
141
+ toJson() {
142
+ // 防止后端序列化策略为下划线, 这里将col、conds、orders中涉及的字段全部转换为驼峰, 因为这些值接口传输给后端时不受反序影响
143
+ // 为了保证后端能正常对应到entity中的字段, 因此转为驼峰(这里是坚信entity中属性是驼峰命名).
144
+ const cols = this.cols.map(col => caseToCamel(col, '_'));
145
+ const conds = this.conds.map(cond => new Cond(caseToCamel(cond.col, '_'), cond.opt, cond.val));
146
+ const orders = this.orders.map(order => new Order(caseToCamel(order.col, '_'), order.asc));
147
+ // 将扩展参数中的"空值"都转换为null, 避免后端获取时参数类型不符引起问题
148
+ const extra = Object.fromEntries(
149
+ Object.entries(this.extra).map(([key, value]) => [key, isEmpty(value) ? null : value])
150
+ );
151
+ return {
152
+ cols: cols,
153
+ conds: conds,
154
+ orders: orders,
155
+ distinct: this.distinct,
156
+ extra: extra
157
+ };
158
+ }
159
+ }
160
+
161
+ export default Query
@@ -0,0 +1,5 @@
1
+ const Rel = Object.freeze({
2
+ AND: "and", OR: "or"
3
+ })
4
+
5
+ export default Rel
@@ -0,0 +1,5 @@
1
+ .fc-dynamic-dialog {
2
+ .el-dialog__body {
3
+ padding: 15px;
4
+ }
5
+ }
@@ -0,0 +1,92 @@
1
+ import {isEmpty, isNumber, ternary} from "./util.js";
2
+
3
+ /**
4
+ * 带有过期时间的 localStorage 封装
5
+ * 实现了 set 和 get 方法来模拟缓存有效期
6
+ */
7
+ const STORAGE_KEY_PREFIX = 'FC:';
8
+
9
+
10
+ /**
11
+ * 保存到localStorage中
12
+ * @param key 会拼接"FC:"前缀
13
+ * @param value any
14
+ * @param minutes 缓存有效期(null/undefined, 均表示不设置有效期)
15
+ */
16
+ export function setToLocalStorage(key, value, minutes) {
17
+ setItem(localStorage, key, value, minutes)
18
+ }
19
+
20
+ /**
21
+ * 从localStorage中获取
22
+ * @param key 会拼接"FC:"前缀
23
+ * @return {string}
24
+ */
25
+ export function getFromLocalStorage(key) {
26
+ return getItem(localStorage, key)
27
+ }
28
+
29
+ export function deleteFromLocalStorage(key) {
30
+ localStorage.removeItem(`${STORAGE_KEY_PREFIX}:${key}`)
31
+ }
32
+
33
+ export function setToSessionStorage(key, value, minutes) {
34
+ setItem(sessionStorage, key, value, minutes)
35
+ }
36
+
37
+ export function getFromSessionStorage(key) {
38
+ return getItem(sessionStorage, key)
39
+ }
40
+
41
+ export function deleteFromSessionStorage(key) {
42
+ sessionStorage.removeItem(`${STORAGE_KEY_PREFIX}${key}`)
43
+ }
44
+
45
+ /**
46
+ * 将数据存储到 localStorage,并设置过期时间
47
+ * @param storage localStorage或sessionStorage
48
+ * @param {string} key 存储的键名 (会被添加前缀)
49
+ * @param {*} value 要存储的任何类型的数据
50
+ * @param {number} minutes 有效期,单位为分钟
51
+ */
52
+ const setItem = (storage, key, value, minutes) => {
53
+ const item = {
54
+ value: value,
55
+ expiry: ternary(isEmpty(minutes), null, new Date().getTime() + minutes * 60 * 1000)
56
+ };
57
+
58
+ try {
59
+ storage.setItem(STORAGE_KEY_PREFIX + key, JSON.stringify(item));
60
+ } catch (error) {
61
+ console.error('存储数据失败:', error);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 从 localStorage 中获取数据,并检查是否过期
67
+ * @param storage localStorage或sessionStorage
68
+ * @param {string} key 存储的键名
69
+ * @returns {*} 如果数据有效则返回存储的值,否则返回 null
70
+ */
71
+ const getItem = (storage, key) => {
72
+ const storedItem = storage.getItem(STORAGE_KEY_PREFIX + key);
73
+ if (!storedItem) {
74
+ return null; // 没有找到缓存
75
+ }
76
+ let item;
77
+ try {
78
+ // 解析存储的 JSON 字符串
79
+ item = JSON.parse(storedItem);
80
+ } catch (error) {
81
+ console.error('解析存储数据失败,清除缓存:', error);
82
+ storage.removeItem(STORAGE_KEY_PREFIX + key);
83
+ return null;
84
+ }
85
+ // 检查是否过期
86
+ if (!isEmpty(item.expiry) && isNumber(item.expiry) && new Date().getTime() > item.expiry) {
87
+ console.log(`${key} has bean expired, removed..`);
88
+ storage.removeItem(STORAGE_KEY_PREFIX + key);
89
+ return null;
90
+ }
91
+ return item.value;
92
+ }
@@ -0,0 +1,133 @@
1
+ import {h, defineComponent, reactive, createVNode, render} from 'vue'
2
+ import {ElDialog, ElButton} from 'element-plus'
3
+ import {getAppContext} from "../index.js"
4
+ import {isFunction} from "./util.js";
5
+
6
+ /**
7
+ * 动态打开弹窗。
8
+ * @param component 弹窗中的组件,可通过emit('ok', data)触发后续then, 或者 通过emit('cancel')取消弹窗触发catch
9
+ * @param props 传递给component的props
10
+ * @param dialogProps 传递给dialog的props, 其中还支持自定义的buttons数组,描述dialog按钮
11
+ * @example
12
+ * openDialog({
13
+ * component: YourComponent,
14
+ * props: {
15
+ * model: {...}
16
+ * },
17
+ * dialogProps: {
18
+ * width: '50%',
19
+ * // dialog支持的props...
20
+ * ...
21
+ * // 自定义的配置
22
+ * okClose: true, // 弹出组件如果emit ok后是否关闭dialog, 默认关闭
23
+ * handleOk: (param) => {}, // ok事件处理的回调函数(作用同then, 但当okClose=true时, then只会执行一次, 单handleOk可以多次执行)
24
+ * handleCancel: (param) => {}, // cancel事件处理回调函数
25
+ * handleCancel: () => {},
26
+ * buttons: [
27
+ * {
28
+ * text: '确定',
29
+ * type: 'primary',
30
+ * onClick: (component) => { // component是你传入的YourComponent组件实例
31
+ * if (!component.validate()) { // YourComponent里提供的校验方法
32
+ * ElMessage.warning('校验不通过!')
33
+ * return // 返回非Promise则不会关闭对话框
34
+ * }
35
+ * return Promise.resolve(component.getModel()) // YourComponent提供的getModel获取表单数据, 走resolve逻辑
36
+ * }
37
+ * },
38
+ * {
39
+ * text: '取消',
40
+ * onClick: (component) => {
41
+ * return Promise.reject() // 走catch逻辑
42
+ * }
43
+ * }
44
+ * // 其它自定义按钮
45
+ * ]
46
+ * }
47
+ * })
48
+ * @returns {Promise<unknown>} 可以通过返回的Promise.then和catch分别处理ok事件(可获取component抛出的参数)和弹窗关闭事件
49
+ */
50
+ export function openDialog({component, props = {}, dialogProps = {}}) {
51
+ // 1.5.12 即使okClose设置为false, 第二次及之后触发ok事件并执行resolve后,外部仍然无法第二次走then逻辑, 因为promise已经成为终态了。
52
+ // 解决方案是:同时支持传入回调函数: handleOk和handleCancel
53
+ const {
54
+ buttons = [],
55
+ okClose = true,
56
+ handleOk: _handleOk,
57
+ handleCancel: _handleCancel,
58
+ ...validDialogProps
59
+ } = dialogProps
60
+
61
+ return new Promise((resolve, reject) => {
62
+ const container = document.createElement('div')
63
+ document.body.appendChild(container)
64
+
65
+ const state = reactive({visible: true})
66
+ let componentRef = null
67
+ let _this = this
68
+
69
+ const DialogWrapper = defineComponent({
70
+ setup() {
71
+ const handleCancel = (who) => {
72
+ state.visible = false
73
+ cleanup()
74
+ if (isFunction(_handleCancel)) {
75
+ _handleCancel.call(_this, who)
76
+ }
77
+ reject(who)
78
+ }
79
+
80
+ const handleOk = (data) => {
81
+ if (okClose === true) {
82
+ state.visible = false
83
+ cleanup()
84
+ }
85
+ if (isFunction(_handleOk)) {
86
+ _handleOk.call(_this, data)
87
+ }
88
+ resolve(data)
89
+ }
90
+
91
+ const cleanup = () => {
92
+ render(null, container) // 卸载 vnode
93
+ container.remove() // 清理 DOM
94
+ }
95
+
96
+ return () => h(ElDialog, {
97
+ modelValue: state.visible,
98
+ 'update:modelValue': (val) => {
99
+ state.visible = val
100
+ if (!val) cleanup()
101
+ },
102
+ onClose: () => handleCancel('dialog'),
103
+ ...validDialogProps
104
+ }, {
105
+ default: () => {
106
+ return h(component, {
107
+ ref: (el) => (componentRef = el),
108
+ ...props,
109
+ onOk: (data) => handleOk(data),
110
+ onCancel: () => handleCancel('component')
111
+ })
112
+ },
113
+ footer: () => buttons.map(btn =>
114
+ h(ElButton, {
115
+ type: btn.type,
116
+ icon: btn.icon,
117
+ size: btn.size,
118
+ onClick: () => {
119
+ const returnVal = btn.onClick?.(componentRef)
120
+ if (!(returnVal instanceof Promise)) return
121
+ returnVal.then(handleOk).catch(() => handleCancel('dialog'))
122
+ }
123
+ }, () => btn.text)
124
+ )
125
+ })
126
+ }
127
+ })
128
+
129
+ const vnode = createVNode(DialogWrapper)
130
+ vnode.appContext = getAppContext() // 集成app的上下文,保证<component :is="" /> 可以找到全局注册的组件
131
+ render(vnode, container)
132
+ })
133
+ }