@gct-paas/render-web 0.1.6-dev.19 → 0.1.6-dev.20

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 (38) hide show
  1. package/dist/index.min.css +1 -1
  2. package/dist/loader.esm.min.js +3 -2
  3. package/es/components/collapse-detail/components/collapse-list.vue_vue_type_script_setup_true_lang.mjs +2 -2
  4. package/es/components/collapse-detail/index.vue.d.ts +9 -1
  5. package/es/components/collapse-detail/index.vue.mjs +2 -2
  6. package/es/components/collapse-detail/index.vue_vue_type_script_setup_true_name_collapse-detail_lang.mjs +4 -3
  7. package/es/components/collapse-detail/{index.vue_vue_type_style_index_0_scoped_53e7e2bf_lang.css → index.vue_vue_type_style_index_0_scoped_b4b9903c_lang.css} +19 -19
  8. package/es/components/field-search-cascader/field-cascader.vue.d.ts +17 -0
  9. package/es/components/field-search-cascader/field-cascader.vue.mjs +8 -0
  10. package/es/components/field-search-cascader/field-cascader.vue_vue_type_script_setup_true_lang.mjs +297 -0
  11. package/es/components/field-search-cascader/field-cascader.vue_vue_type_style_index_0_scoped_cb5e4d67_lang.css +52 -0
  12. package/es/components/field-search-cascader/field-cascader.vue_vue_type_style_index_1_lang.css +3 -0
  13. package/es/components/field-search-cascader/index.d.ts +2 -0
  14. package/es/components/field-search-cascader/index.mjs +1 -0
  15. package/es/components/index.d.ts +2 -0
  16. package/es/components/index.mjs +4 -0
  17. package/es/components/rich-editor/index.d.ts +2 -0
  18. package/es/components/rich-editor/index.mjs +1 -0
  19. package/es/components/rich-editor/rich-editor.vue.d.ts +22 -0
  20. package/es/components/rich-editor/rich-editor.vue.mjs +5 -0
  21. package/es/components/rich-editor/rich-editor.vue_vue_type_script_setup_true_lang.mjs +150 -0
  22. package/es/components/rich-editor/style.css +747 -0
  23. package/es/constants/xlsx-parser.d.ts +15 -0
  24. package/es/constants/xlsx-parser.mjs +58 -0
  25. package/es/enums/xlsx-parser.d.ts +293 -0
  26. package/es/enums/xlsx-parser.mjs +36 -0
  27. package/es/index.d.ts +1 -0
  28. package/es/index.mjs +5 -1
  29. package/es/interface/xlsx-parser/base.d.ts +151 -0
  30. package/es/interface/xlsx-parser/index.d.ts +246 -0
  31. package/es/types/shims-modules.d.ts +11 -0
  32. package/es/utils/cell-border.d.ts +73 -0
  33. package/es/utils/cell-border.mjs +203 -0
  34. package/es/utils/index.d.ts +1 -0
  35. package/es/utils/index.mjs +1 -0
  36. package/es/utils/xlsx-parser.d.ts +141 -0
  37. package/es/utils/xlsx-parser.mjs +262 -0
  38. package/package.json +16 -11
@@ -0,0 +1,262 @@
1
+ import { FIELD_TYPE_BUSINESS } from "../enums/xlsx-parser.mjs";
2
+ import { DefaultPaper, FIELD_PROP_LABEL_MAP, FIELD_TYPE_LABEL_MAP } from "../constants/xlsx-parser.mjs";
3
+ import { CellBorder } from "./cell-border.mjs";
4
+ import { FIELD_TYPE, FIELD_TYPE_TRACE, t } from "@gct-paas/core";
5
+ import { cloneDeep } from "lodash-es";
6
+ import ExcelJs from "exceljs";
7
+ import toPx from "unit-to-px";
8
+ //#region src/utils/xlsx-parser.ts
9
+ var isTypeInGroup = (type, group) => group.includes(type);
10
+ var generateAutoFieldKey = (type, fieldGroup, keyList) => {
11
+ if (!isTypeInGroup(type, fieldGroup)) return;
12
+ const nums = keyList.filter((i) => i.startsWith(type)).map((i) => parseInt(i.match(/\d+/)?.[0] || "0", 10));
13
+ return `${type}_${(nums.length ? Math.max(...nums) : 0) + 1}_`;
14
+ };
15
+ var FieldPropLabels = Object.entries(FIELD_PROP_LABEL_MAP);
16
+ var FieldTypeLabels = Object.entries(FIELD_TYPE_LABEL_MAP);
17
+ var TRACE_FIELDS = Object.values(FIELD_TYPE_TRACE);
18
+ var BUSINESS_FIELDS = Object.values(FIELD_TYPE_BUSINESS);
19
+ var XlsxParser = class XlsxParser {
20
+ static async xlsx2json(file) {
21
+ const workbook = new ExcelJs.Workbook();
22
+ const xlsxData = await workbook.xlsx.load(file);
23
+ const paperSheet = workbook.getWorksheet(t("sys.onlineForm.formStyle")) || workbook.getWorksheet();
24
+ if (!paperSheet) return;
25
+ return XlsxParser.sheetToPaper(paperSheet, xlsxData);
26
+ }
27
+ static async xlsx2jsonWithFields(file, keyList) {
28
+ const workbook = new ExcelJs.Workbook();
29
+ const xlsxData = await workbook.xlsx.load(file);
30
+ const paperSheet = workbook.getWorksheet(t("sys.onlineForm.formStyle")) || workbook.getWorksheet();
31
+ const fieldSheet = workbook.getWorksheet(t("sys.onlineForm.formFields"));
32
+ const paper = paperSheet ? XlsxParser.sheetToPaper(paperSheet, xlsxData) : null;
33
+ const fields = fieldSheet ? XlsxParser.sheetToFields(fieldSheet, keyList) : null;
34
+ const paperFields = [];
35
+ paper?.cells?.forEach((row, rowIndex) => {
36
+ row.forEach((cell, colIndex) => {
37
+ console.log("cell", cell);
38
+ const matches = typeof cell?.value === "string" ? cell?.value?.match(/^\$\{(.+?)\}$/) : null;
39
+ if (!matches) return;
40
+ const matchKey = matches[1];
41
+ const fieldMeta = fields?.find((item) => item.tmpOldKey === matchKey || item.key === matchKey || item.name === matchKey);
42
+ if (!fieldMeta) return;
43
+ paperFields.push({
44
+ x: colIndex + 1,
45
+ y: rowIndex + 1,
46
+ fieldKey: fieldMeta.key,
47
+ fieldName: fieldMeta.name,
48
+ fieldType: fieldMeta.type
49
+ });
50
+ });
51
+ });
52
+ return {
53
+ paper,
54
+ fields,
55
+ paperFields
56
+ };
57
+ }
58
+ static sheetToPaper(paperSheet, xlsxData) {
59
+ const SheetRowCount = Math.min(paperSheet.dimensions.bottom, 300);
60
+ const SheetColCount = Math.min(paperSheet.dimensions.right, 75);
61
+ const paper = {};
62
+ const { defaultRowHeight, defaultColWidth } = paperSheet.properties;
63
+ const defaultRowHeightPx = parseInt(toPx(`${defaultRowHeight}pt`));
64
+ const rows = [];
65
+ Array(SheetRowCount).fill("").forEach((_r, i) => {
66
+ const row = paperSheet._rows?.[i];
67
+ rows.push({ height: parseInt(toPx(`${row?.height ?? defaultRowHeight}pt`)) });
68
+ });
69
+ paper.rows = rows;
70
+ const cols = [];
71
+ Array(SheetColCount).fill("").forEach((_c, i) => {
72
+ const { width } = paperSheet.columns[i];
73
+ const _w = width ?? defaultColWidth;
74
+ cols.push({ width: _w === void 0 ? 80 : Math.floor(_w * toPx("ch")) });
75
+ });
76
+ paper.cols = cols;
77
+ const cells = Array(SheetRowCount).fill("").map(() => Array(SheetColCount).fill("").map(() => ({})));
78
+ Array(SheetRowCount).fill("").forEach((_, rowIndex) => {
79
+ if (!paperSheet._rows?.[rowIndex]) return;
80
+ Array(SheetColCount).fill("").forEach((_, colIndex) => {
81
+ const cell = paperSheet._rows?.[rowIndex]._cells?.[colIndex];
82
+ if (!cell) return;
83
+ const { alignment, fill, font } = cell.style;
84
+ const cellName = cell._address;
85
+ const cellStyle = {
86
+ "text-align": alignment?.horizontal ?? "left",
87
+ "vertical-align": alignment?.vertical ?? "middle",
88
+ "background-color": fill?.fgColor?.argb?.substring(2).padStart(7, "#"),
89
+ color: font?.color?.argb?.substring(2).padStart(7, "#"),
90
+ "font-size": `${font?.size < 12 ? 12 : font?.size}px`,
91
+ "white-space": alignment?.wrapText ? "pre-line" : void 0,
92
+ "line-height": "1em"
93
+ };
94
+ if (alignment?.wrapText) cellStyle["line-height"] = "1.5em";
95
+ cells[rowIndex][colIndex].style = cellStyle;
96
+ if (cellName !== cell.master.address) return;
97
+ let cellValue = "";
98
+ if (typeof cell.value !== "object") cellValue = cell.value;
99
+ else if (typeof cell.text !== "object") cellValue = cell.text;
100
+ cells[rowIndex][colIndex].value = cellValue;
101
+ });
102
+ });
103
+ paper.cells = cells;
104
+ const mergedCells = [];
105
+ Object.entries(paperSheet._merges ?? {}).forEach((m) => {
106
+ const { top: t, bottom: b, left: l, right: r } = m[1];
107
+ if (t > SheetRowCount || l > SheetColCount) return;
108
+ mergedCells.push({
109
+ t,
110
+ l,
111
+ b: Math.min(SheetRowCount, b),
112
+ r: Math.min(SheetColCount, r)
113
+ });
114
+ });
115
+ paper.mergedCells = mergedCells;
116
+ /**
117
+ * 抽离边框设置逻辑 与设计器中保持一致
118
+ */
119
+ Array(SheetRowCount).fill("").forEach((_, rowIndex) => {
120
+ if (!paperSheet._rows?.[rowIndex]) return;
121
+ Array(SheetColCount).fill("").forEach((_, colIndex) => {
122
+ const cell = paperSheet._rows?.[rowIndex]._cells?.[colIndex];
123
+ if (!cell) return;
124
+ const { border } = cell.style;
125
+ if (border?.top) CellBorder.setTop(colIndex + 1, rowIndex + 1, paper);
126
+ if (border?.bottom) CellBorder.setBottom(colIndex + 1, rowIndex + 1, paper);
127
+ if (border?.left) CellBorder.setLeft(colIndex + 1, rowIndex + 1, paper);
128
+ if (border?.right) CellBorder.setRight(colIndex + 1, rowIndex + 1, paper);
129
+ });
130
+ });
131
+ const medias = (xlsxData.media ?? []).map((m) => {
132
+ return {
133
+ id: Math.random().toString(36).substring(2, 10),
134
+ src: `data:image/${m.extension};base64,` + m.buffer.toString("base64")
135
+ };
136
+ });
137
+ const images = [];
138
+ paperSheet._media?.forEach((m) => {
139
+ const { imageId, range } = m;
140
+ const imageLayout = {
141
+ height: parseInt(toPx(`${(range.br.nativeRowOff - range.tl.nativeRowOff) / 914400}in`)) + (range.br.nativeRow - range.tl.nativeRow > 0 ? Array(range.br.nativeRow - range.tl.nativeRow).fill("").reduce((total, _r, i) => {
142
+ total = total + (paper.rows?.[i + range.tl.nativeRow]?.height ?? defaultRowHeightPx);
143
+ return total;
144
+ }, 0) : 0),
145
+ width: parseInt(toPx(`${(range.br.nativeColOff - range.tl.nativeColOff) / 914400}in`)) + (range.br.nativeCol - range.tl.nativeCol > 0 ? Array(range.br.nativeCol - range.tl.nativeCol).fill("").reduce((total, _c, i) => {
146
+ total = total + paper.cols?.[i + range.tl.nativeCol].width;
147
+ return total;
148
+ }, 0) : 0),
149
+ top: parseInt(toPx(`${range.tl.nativeRowOff / 914400}in`)),
150
+ left: parseInt(toPx(`${range.tl.nativeColOff / 914400}in`))
151
+ };
152
+ const deltaX = Array(range.tl.nativeCol).fill("").reduce((result, _i, index) => {
153
+ result += paper.cols?.[index]?.width ?? 0;
154
+ return result;
155
+ }, 0);
156
+ const deltaY = Array(range.tl.nativeRow).fill("").reduce((result, _i, index) => {
157
+ result += paper.rows?.[index]?.height ?? defaultRowHeightPx;
158
+ return result;
159
+ }, 0);
160
+ const img = {
161
+ id: Math.random().toString(36).substring(2, 10),
162
+ mediaId: medias[imageId].id,
163
+ layout: {
164
+ height: imageLayout.height,
165
+ width: imageLayout.width,
166
+ top: imageLayout.top + deltaY,
167
+ left: imageLayout.left + deltaX
168
+ }
169
+ };
170
+ images.push(img);
171
+ });
172
+ paper.medias = medias;
173
+ paper.images = images;
174
+ return {
175
+ ...cloneDeep(DefaultPaper),
176
+ ...paper
177
+ };
178
+ }
179
+ /**
180
+ * 根据 sheet 内容解析字段信息
181
+ * @param sheet
182
+ * @returns
183
+ */
184
+ static sheetToFields(sheet, keyList) {
185
+ const SheetRowCount = Math.min(sheet.rowCount, 300);
186
+ const SheetColCount = Math.min(sheet.columnCount, 10);
187
+ const colFieldPropMap = /* @__PURE__ */ new Map();
188
+ Array(SheetColCount).fill("").forEach((_, colIndex) => {
189
+ const cell = sheet._rows?.[0]._cells?.[colIndex];
190
+ const fieldProp = FieldPropLabels.find((f) => f[1] === (cell?.text ?? "").replaceAll("*", "").trim());
191
+ if (fieldProp) colFieldPropMap.set(colIndex, fieldProp[0]);
192
+ });
193
+ const fields = [];
194
+ Array(SheetRowCount).fill("").forEach((_, rowIndex) => {
195
+ if (rowIndex === 0) return;
196
+ if (!sheet._rows?.[rowIndex]) return;
197
+ const field = {};
198
+ Array(SheetColCount).fill("").forEach((_, colIndex) => {
199
+ const cell = sheet._rows?.[rowIndex]._cells?.[colIndex];
200
+ if (colFieldPropMap.has(colIndex)) field[colFieldPropMap.get(colIndex)] = cell?.text ?? "";
201
+ });
202
+ fields.push(field);
203
+ });
204
+ const cloneKeyList = [...keyList];
205
+ fields.forEach((f) => {
206
+ XlsxParser._field2Meta(f, cloneKeyList);
207
+ });
208
+ return fields;
209
+ }
210
+ /**
211
+ * 字段信息转换为元数据
212
+ * @param field
213
+ */
214
+ static _field2Meta(field, keyList) {
215
+ const { type, required } = field;
216
+ field.required = required === t("sys.true") ? 1 : 0;
217
+ const fieldType = FieldTypeLabels.find((f) => f[1] === type);
218
+ if (fieldType) field.type = fieldType[0];
219
+ else field.type = FIELD_TYPE.TEXT;
220
+ if (isTypeInGroup(field.type, BUSINESS_FIELDS)) {
221
+ field.tmpOldKey = field.key;
222
+ field.key = generateAutoFieldKey(field.type, BUSINESS_FIELDS, []);
223
+ } else if (isTypeInGroup(field.type, TRACE_FIELDS)) {
224
+ field.tmpOldKey = field.key;
225
+ const key = generateAutoFieldKey(field.type, TRACE_FIELDS, keyList);
226
+ field.key = key;
227
+ keyList.push(key);
228
+ }
229
+ field.uniqueConstraint = { type: field.uniqueConstraint === t("sys.true") ? "GLOBAL" : "NONE" };
230
+ field.disabled = field.disabled === t("sys.true") ? 1 : 0;
231
+ }
232
+ /**
233
+ * @param paper 导入的纸张数据
234
+ * @param range 最大显示范围
235
+ * @param mode 缩放模式 x: 横向 y: 纵向
236
+ */
237
+ static contentFitToPaper(paper, range, mode = "x") {
238
+ const contentWidth = paper?.cols.reduce((total, item) => {
239
+ total += item.width;
240
+ return total;
241
+ }, 0);
242
+ const contentHeight = paper?.rows.reduce((total, item) => {
243
+ total += item.height;
244
+ return total;
245
+ }, 0);
246
+ const viewportWidth = parseInt(toPx(range[0]));
247
+ const viewportHeight = parseInt(toPx(range[1]));
248
+ const xRatio = contentWidth / viewportWidth;
249
+ const yRatio = contentHeight / viewportHeight;
250
+ const maxRatio = mode === "x" ? xRatio : Math.max(xRatio, yRatio);
251
+ if (maxRatio > 1) {
252
+ paper.cols.forEach((item) => {
253
+ item.width = item.width / maxRatio;
254
+ });
255
+ paper.rows.forEach((item) => {
256
+ item.height = item.height / maxRatio;
257
+ });
258
+ }
259
+ }
260
+ };
261
+ //#endregion
262
+ export { XlsxParser };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gct-paas/render-web",
3
- "version": "0.1.6-dev.19",
3
+ "version": "0.1.6-dev.20",
4
4
  "type": "module",
5
5
  "description": "paas 平台网页端底包",
6
6
  "loader": "dist/loader.esm.min.js",
@@ -31,24 +31,29 @@
31
31
  "license": "MIT",
32
32
  "author": "gct",
33
33
  "dependencies": {
34
+ "@gct-paas/api": "^0.1.6-dev.11",
35
+ "@vueuse/core": "^14.1.0",
36
+ "@wangeditor/editor-for-vue": "^5.1.12",
34
37
  "ant-design-vue": "~3.2.20",
35
38
  "colord": "^2.9.3",
36
39
  "exceljs": "^4.4.0",
37
40
  "lodash-es": "^4.17.23",
41
+ "unit-to-px": "^1.0.5",
38
42
  "vue": "^3.5.30",
39
- "@gct-paas/core-web": "0.1.6-dev.19",
40
- "@gct-paas/core": "0.1.6-dev.19",
41
- "@gct-paas/render": "0.1.6-dev.19",
42
- "@gct-paas/schema": "0.1.6-dev.19",
43
- "@gct-paas/scss": "0.1.6-dev.19"
43
+ "@gct-paas/core": "0.1.6-dev.20",
44
+ "@gct-paas/core-web": "0.1.6-dev.20",
45
+ "@gct-paas/render": "0.1.6-dev.20",
46
+ "@gct-paas/schema": "0.1.6-dev.20",
47
+ "@gct-paas/scss": "0.1.6-dev.20"
44
48
  },
45
49
  "peerDependencies": {
50
+ "@gct-paas/api": "^0.1.6-dev.11",
46
51
  "vue": ">=3",
47
- "@gct-paas/render": "0.1.6-dev.19",
48
- "@gct-paas/core": "0.1.6-dev.19",
49
- "@gct-paas/schema": "0.1.6-dev.19",
50
- "@gct-paas/core-web": "0.1.6-dev.19",
51
- "@gct-paas/scss": "0.1.6-dev.19"
52
+ "@gct-paas/core-web": "0.1.6-dev.20",
53
+ "@gct-paas/render": "0.1.6-dev.20",
54
+ "@gct-paas/schema": "0.1.6-dev.20",
55
+ "@gct-paas/core": "0.1.6-dev.20",
56
+ "@gct-paas/scss": "0.1.6-dev.20"
52
57
  },
53
58
  "devDependencies": {
54
59
  "@types/lodash-es": "^4.17.12"