tor-univer-sheet 1.0.16 → 1.0.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tor-univer-sheet",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "style": "./dist/style.css",
5
5
  "description": "基于 Univer 的 Vue3 电子表格组件",
6
6
  "author": "tortormore",
@@ -18,8 +18,7 @@
18
18
  "./style.css": "./dist/style.css"
19
19
  },
20
20
  "files": [
21
- "dist",
22
- "src"
21
+ "dist"
23
22
  ],
24
23
  "scripts": {
25
24
  "dev": "vite",
package/src/App.vue DELETED
@@ -1,14 +0,0 @@
1
- <template>
2
- <div style="width: 100%; height: 100vh"></div>
3
- </template>
4
-
5
- <script setup lang="ts">
6
- import { ref, onMounted } from 'vue'
7
- import { ModeEnum } from './components/UniverSheet/UniverSheet.data'
8
-
9
- const sheetRef = ref()
10
-
11
- onMounted(() => {
12
- sheetRef.value?.createUniverSheets()
13
- })
14
- </script>
@@ -1,59 +0,0 @@
1
- import {
2
- ICellData,
3
- IObjectMatrixPrimitiveType,
4
- } from '@univerjs/presets'
5
-
6
-
7
- export function getNumColumns(cells: IObjectMatrixPrimitiveType<ICellData>) {
8
- const result = Object.entries(cells).reduce((acc, [rowNum, cols]) => {
9
- const colsNum = Math.max(...Object.keys(cols).map(Number))
10
- if (colsNum > acc) {
11
- acc = Number(colsNum)
12
- } else {
13
- acc = Number(acc) || 0
14
- }
15
- return acc
16
- }, 0)
17
- return result
18
- }
19
- /**
20
- * 智能合并单元格数据
21
- * 保留原有单元格的属性(如公式、值等),用新数据进行更新
22
- * @param originalCellData - 原始单元格数据(来自 sheetSnapshot.cellData)
23
- * @param newCells - 新的单元格数据(来自后端或自生成)
24
- * @returns 合并后的单元格数据
25
- */
26
- export function mergeCellData(
27
- originalCellData: IObjectMatrixPrimitiveType<ICellData> | undefined,
28
- newCells: IObjectMatrixPrimitiveType<ICellData>
29
- ): IObjectMatrixPrimitiveType<ICellData> {
30
- const result = JSON.parse(JSON.stringify(originalCellData || {})) as IObjectMatrixPrimitiveType<ICellData>
31
-
32
- for (const [rowNum, cols] of Object.entries(newCells)) {
33
- if (!result[rowNum]) {
34
- result[rowNum] = {}
35
- }
36
-
37
- for (const [colNum, newCellData] of Object.entries(cols)) {
38
- const cellData = newCellData as ICellData
39
- const originalCell = result[rowNum]?.[colNum]
40
-
41
- if (originalCell) {
42
- result[rowNum][colNum] = {
43
- ...originalCell,
44
- ...cellData,
45
- custom: {
46
- ...originalCell.custom,
47
- ...(cellData.custom || {})
48
- }
49
- }
50
- } else {
51
- result[rowNum][colNum] = cellData
52
- }
53
- }
54
- }
55
-
56
- return result
57
- }
58
-
59
-
@@ -1,533 +0,0 @@
1
- import { isArray, isEmpty } from '@/utils/is'
2
- import dayjs from 'dayjs'
3
- import { ICellData, IWorksheetData, IObjectMatrixPrimitiveType, CellValueType } from '@univerjs/presets'
4
- import { decimal } from '@/utils/decimal'
5
-
6
-
7
-
8
- export enum CycleTypeEnum {
9
- 无 = 'no',
10
- 年 = 'year',
11
- 月 = 'month',
12
- 周 = 'week',
13
- 天 = 'day',
14
- 班组 = 'shift',
15
- 小时 = 'hour',
16
- 半小时 = 'half_hour'
17
- }
18
-
19
- export enum ModeEnum {
20
- view = 'view',
21
- edit = 'edit'
22
- }
23
-
24
- export interface UniverSheetsProps {
25
- mode: ModeEnum
26
- showImportFilePlugin?: boolean
27
- showIndicatorsContextMenuPlugin?: boolean
28
- showSyncContextMenuPlugin?: boolean
29
- showTimeConfigContextMenuPlugin?: boolean
30
- license: string
31
- }
32
-
33
- export async function initDateRange(cycleType: CycleTypeEnum, date: string[] | string): Promise<string[]> {
34
- if (!date) return Promise.reject('日期不能为空')
35
- switch (cycleType) {
36
- case CycleTypeEnum.年:
37
- if (isArray(date)) {
38
- return Promise.resolve(date)
39
- }
40
- const parsedYearDate = dayjs(date)
41
- if (!parsedYearDate.isValid()) {
42
- return Promise.reject('无效的日期格式')
43
- }
44
- const year = parsedYearDate.year()
45
- const startMonth = `${year}-01`
46
- const endMonth = `${year}-12`
47
-
48
- return Promise.resolve([startMonth, endMonth])
49
- case CycleTypeEnum.月:
50
- if (isArray(date)) {
51
- return Promise.resolve(date)
52
- }
53
- const parsedMonthDate = dayjs(date)
54
- if (!parsedMonthDate.isValid()) {
55
- return Promise.reject('无效的日期格式')
56
- }
57
- const monthStartDate = parsedMonthDate.startOf('month').format('YYYY-MM-DD')
58
- const monthEndDate = parsedMonthDate.endOf('month').format('YYYY-MM-DD')
59
-
60
- return Promise.resolve([monthStartDate, monthEndDate])
61
- case CycleTypeEnum.天:
62
- if (isArray(date)) {
63
- return Promise.resolve(date)
64
- }
65
- const parsedDayDate = dayjs(date)
66
- if (!parsedDayDate.isValid()) {
67
- return Promise.reject('无效的日期格式')
68
- }
69
- const startOfDay = parsedDayDate.startOf('day').format('YYYY-MM-DD HH:mm:ss')
70
- const endOfDay = parsedDayDate.endOf('day').format('YYYY-MM-DD HH:mm:ss')
71
- return Promise.resolve([startOfDay, endOfDay])
72
- default:
73
- return Promise.reject('不支持的周期类型')
74
- }
75
- }
76
-
77
- export enum dateTypeEnum {
78
- year = 'year',
79
- month = 'month',
80
- day = 'day',
81
- hour = 'hour'
82
- }
83
-
84
- function getDiffNum(startDate, endDate, dateType: dateTypeEnum) {
85
- if (!dateType) return 0
86
- const format = {
87
- year: 'YYYY',
88
- month: 'YYYY-MM',
89
- day: 'YYYY-MM-DD',
90
- hour: 'HH:mm:ss'
91
- }[dateType]
92
- if (['day', 'hour'].includes(dateType)) {
93
- return dayjs(endDate, format).diff(dayjs(startDate, format), dateType) + 1
94
- }
95
- return dayjs(endDate, format).diff(dayjs(startDate, format), dateType)
96
- }
97
-
98
- function getForwardPushTimes(startDate: string, forwardPushTime: number, dateType: dateTypeEnum): string {
99
- if (!dateType) {
100
- throw new Error('日期类型不能为空')
101
- }
102
- const format = {
103
- year: 'YYYY',
104
- month: 'YYYY-MM',
105
- day: 'YYYY-MM-DD',
106
- hour: 'HH:mm:ss'
107
- }[dateType]
108
- return dayjs(startDate).subtract(forwardPushTime, dateType).format(format)
109
- }
110
-
111
- function generateTime(base, type, num, times) {
112
- const format = {
113
- year: 'YYYY',
114
- month: 'YYYY-MM',
115
- day: 'YYYY-MM-DD',
116
- hour: 'YYYY-MM-DD HH:mm:ss'
117
- }[type]
118
- return dayjs(base, format)
119
- .add(num * times, type)
120
- .format(format)
121
- }
122
-
123
- export interface IGenerateIndicatorsCellsParams {
124
- extraArgs: any
125
- rangeData: string[]
126
- currentDay?: string
127
- }
128
-
129
- export type TeamDataType = {
130
- teamId: string // 班组id
131
- teamName: string // 班组名称
132
- shiftId: string // 班次id
133
- shiftName: string // 班次名称
134
- scheduleConfigName: string // 排班配置名称
135
- scheduleConfigId: string // 排班配置ID
136
- workName: string // 作业名称
137
- workCoding: string // 作业编码
138
- startDatetime: string // 开始时间
139
- endDatetime: string // 结束时间
140
- }
141
-
142
- function ensureCellExists(acc: any, rowNum: string | number, colNum: string | number): any {
143
- // 确保 acc[rowNum] 存在
144
- if (!acc[rowNum]) {
145
- acc[rowNum] = {}
146
- }
147
-
148
- // 确保 acc[rowNum][colNum] 存在
149
- if (!acc[rowNum][colNum]) {
150
- acc[rowNum][colNum] = {}
151
- }
152
-
153
- return acc[rowNum][colNum]
154
- }
155
-
156
- export async function filterIndicatorsCell(cellData: IObjectMatrixPrimitiveType<ICellData>) {
157
- if (!cellData) {
158
- throw new Error('cellData is required')
159
- }
160
- const result = Object.entries(cellData).reduce((acc, cur: any) => {
161
- const [rowNum, cols] = cur
162
- for (const [colNum, cellData] of Object.entries(cols)) {
163
- const { custom, v } = cellData as ICellData
164
- if (!custom) continue
165
- const { cellType } = custom
166
- if (cellType === 'indicator') {
167
- const targetCell = ensureCellExists(acc, rowNum, colNum)
168
- targetCell.custom = custom
169
- targetCell.v = v
170
- }
171
- }
172
- return acc
173
- }, {})
174
- if (!result || isEmpty(result)) {
175
- return Promise.reject(new Error('No data found'))
176
- }
177
- return Promise.resolve(result)
178
- }
179
-
180
- function createTimeCells({
181
- acc,
182
- params,
183
- initRowNum,
184
- initColNum,
185
- cellData
186
- }: {
187
- acc: any
188
- params: IGenerateIndicatorsCellsParams
189
- initRowNum: number
190
- initColNum: number
191
- cellData: any
192
- }) {
193
- const { rangeData, currentDay, extraArgs } = params
194
- const teamData: any = extraArgs?.teamData || {}
195
- const { cycleType, timeIncrement, forwardPush, copyType, copyInterval, defaultShift } = cellData.custom as any
196
-
197
- // 计算生成的行、列数量
198
- let copyNum = 0
199
-
200
- switch (cycleType) {
201
- case CycleTypeEnum.天: {
202
- let forwardServenDay: string = ''
203
- if (forwardPush) {
204
- forwardServenDay = getForwardPushTimes(rangeData[0], 6, dateTypeEnum.day)
205
- }
206
-
207
- // 不拓展的情况
208
- if (!copyType) {
209
- let businessDate: string = ''
210
- if (forwardPush) {
211
- businessDate = forwardServenDay
212
- } else {
213
- businessDate = rangeData[0]
214
- }
215
-
216
- // 使用封装方法确保结构存在
217
- const targetCell = ensureCellExists(acc, initRowNum, initColNum)
218
- targetCell.v = businessDate
219
- targetCell.t = CellValueType.STRING
220
- break
221
- }
222
-
223
- // 拓展的情况
224
- if (forwardPush) {
225
- copyNum = getDiffNum(forwardServenDay, rangeData[0], dateTypeEnum.day)
226
- } else {
227
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.day)
228
- }
229
-
230
- // 向右增加列,向下增加行
231
- for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
232
- // 处理跨行跨列
233
- const index = i * (copyInterval + 1)
234
- let businessDate: string = ''
235
- if (forwardPush) {
236
- businessDate = generateTime(forwardServenDay, dateTypeEnum.day, i, timeIncrement)
237
- } else {
238
- businessDate = generateTime(rangeData[0], dateTypeEnum.day, i, timeIncrement)
239
- }
240
-
241
- const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
242
- const newColNum = copyType === 'right' ? initColNum + index : initColNum
243
-
244
- // 使用封装方法确保新位置结构存在
245
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
246
- targetCell.v = businessDate
247
- targetCell.t = CellValueType.STRING
248
- }
249
- break
250
- }
251
-
252
- case CycleTypeEnum.月: {
253
- // 不拓展的情况
254
- if (!copyType) {
255
- const targetCell = ensureCellExists(acc, initRowNum, initColNum)
256
- targetCell.v = rangeData[0]
257
- targetCell.t = CellValueType.STRING
258
- break
259
- }
260
-
261
- // 向右增加列,向下增加行
262
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.month)
263
- for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
264
- // 处理跨行跨列
265
- const index = i * (copyInterval + 1)
266
- const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
267
- const newColNum = copyType === 'right' ? initColNum + index : initColNum
268
-
269
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
270
- targetCell.v = generateTime(rangeData[0], dateTypeEnum.month, i, timeIncrement)
271
- targetCell.t = CellValueType.STRING
272
- }
273
- break
274
- }
275
-
276
- case CycleTypeEnum.年: {
277
- // 不拓展的情况
278
- if (!copyType) {
279
- const targetCell = ensureCellExists(acc, initRowNum, initColNum)
280
- targetCell.v = rangeData[0]
281
- targetCell.t = CellValueType.STRING
282
- break
283
- }
284
-
285
- // 向右增加列,向下增加行
286
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.year)
287
- for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
288
- // 处理跨行跨列
289
- const index = i * (copyInterval + 1)
290
- const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
291
- const newColNum = copyType === 'right' ? initColNum + index : initColNum
292
-
293
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
294
- targetCell.v = generateTime(rangeData[0], dateTypeEnum.year, i, timeIncrement)
295
- targetCell.t = CellValueType.STRING
296
- }
297
- break
298
- }
299
- case CycleTypeEnum.小时: {
300
- if (!copyType) {
301
- const targetCell = ensureCellExists(acc, initRowNum, initColNum)
302
- targetCell.t = CellValueType.STRING
303
- if (defaultShift) {
304
- targetCell.v = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
305
- break
306
- }
307
- targetCell.v = dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
308
- break
309
- }
310
- copyNum = getDiffNum(teamData?.startDatetime, teamData?.endDatetime, dateTypeEnum.hour)
311
- for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
312
- // 处理跨行跨列
313
- const index = i * (copyInterval + 1)
314
- const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
315
- const newColNum = copyType === 'right' ? initColNum + index : initColNum
316
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
317
- targetCell.t = CellValueType.STRING
318
- if (defaultShift) {
319
- const laterOneHour = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
320
- targetCell.v = generateTime(laterOneHour, dateTypeEnum.hour, i, timeIncrement)
321
- continue
322
- }
323
- targetCell.v = generateTime(dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dateTypeEnum.hour, i, timeIncrement)
324
- }
325
- }
326
- }
327
- }
328
-
329
- export async function generateIndicatorsCells(
330
- cells: IObjectMatrixPrimitiveType<ICellData>,
331
- params: IGenerateIndicatorsCellsParams
332
- ): Promise<ICellData> {
333
- if (!cells) {
334
- return Promise.reject('没有可用的单元格数据')
335
- }
336
-
337
- const { extraArgs, rangeData } = params
338
- if (!rangeData.length) {
339
- return Promise.reject('处理时间范围失败, rangeData不能为空')
340
- }
341
- const teamData: TeamDataType = extraArgs?.teamData || {}
342
-
343
- const currentDay = params?.currentDay || dayjs().format('YYYY-MM-DD')
344
-
345
- const result = Object.entries(cells).reduce((acc, cur) => {
346
- const [rowNum, cols] = cur
347
-
348
- for (const [colNum, cellData] of Object.entries(cols)) {
349
- const { custom } = cellData as ICellData
350
- if (!custom) continue
351
-
352
- const { cellType, cycleType, timeIncrement, forwardPush, copyType, copyInterval, defaultShift } = custom as any
353
-
354
- if (cellType === 'time') {
355
- createTimeCells({ acc, params, initRowNum: Number(rowNum), initColNum: Number(colNum), cellData })
356
- continue
357
- }
358
-
359
- const customData = {
360
- cycleType,
361
- indicatorName: custom.indicatorName,
362
- indicatorCode: custom.indicatorCode,
363
- indicatorId: custom.indicatorId,
364
- indicatorDimensionName: custom.indicatorDimensionName,
365
- indicatorDimensionConfig: custom.indicatorDimensionConfig,
366
- required: custom.required,
367
- cellType: custom.cellType,
368
- defaultShift: custom.defaultShift
369
- }
370
-
371
- let copyNum = 0
372
- switch (cycleType) {
373
- case CycleTypeEnum.天: {
374
- let forwardServenDay: string = ''
375
- if (forwardPush) {
376
- forwardServenDay = getForwardPushTimes(rangeData[0], 6, dateTypeEnum.day)
377
- }
378
-
379
- if (!copyType) {
380
- let businessDate: string = ''
381
- if (forwardPush) {
382
- businessDate = forwardServenDay
383
- } else {
384
- businessDate = rangeData[0]
385
- }
386
-
387
- // 使用封装方法确保结构存在
388
- const targetCell = ensureCellExists(acc, rowNum, colNum)
389
- targetCell.custom = {
390
- ...customData,
391
- businessDate
392
- }
393
- if (defaultShift) {
394
- targetCell.custom.teamData = teamData
395
- }
396
- break
397
- }
398
-
399
- if (forwardPush) {
400
- copyNum = getDiffNum(forwardServenDay, rangeData[0], dateTypeEnum.day)
401
- } else {
402
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.day)
403
- }
404
-
405
- for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
406
- const index = i * (copyInterval + 1)
407
- let businessDate: string = ''
408
- if (forwardPush) {
409
- businessDate = generateTime(forwardServenDay, dateTypeEnum.day, i, timeIncrement)
410
- } else {
411
- businessDate = generateTime(rangeData[0], dateTypeEnum.day, i, timeIncrement)
412
- }
413
-
414
- const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
415
- const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
416
-
417
- // 使用封装方法确保新位置结构存在
418
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
419
- targetCell.custom = {
420
- ...customData,
421
- businessDate
422
- }
423
- if (defaultShift) {
424
- targetCell.custom.teamData = teamData
425
- }
426
- }
427
- break
428
- }
429
-
430
- case CycleTypeEnum.月: {
431
- if (!copyType) {
432
- const targetCell = ensureCellExists(acc, rowNum, colNum)
433
- targetCell.custom = {
434
- ...customData,
435
- businessDate: rangeData[0]
436
- }
437
- break
438
- }
439
-
440
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.month)
441
- for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
442
- const index = i * (copyInterval + 1)
443
- const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
444
- const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
445
-
446
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
447
- targetCell.custom = {
448
- ...customData,
449
- businessDate: generateTime(rangeData[0], dateTypeEnum.month, i, timeIncrement)
450
- }
451
- }
452
- break
453
- }
454
-
455
- case CycleTypeEnum.年: {
456
- if (!copyType) {
457
- const targetCell = ensureCellExists(acc, rowNum, colNum)
458
- targetCell.custom = {
459
- ...customData,
460
- businessDate: rangeData[0]
461
- }
462
- break
463
- }
464
-
465
- copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.year)
466
- for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
467
- const index = i * (copyInterval + 1)
468
- const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
469
- const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
470
-
471
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
472
- targetCell.custom = {
473
- ...customData,
474
- businessDate: generateTime(rangeData[0], dateTypeEnum.year, i, timeIncrement)
475
- }
476
- }
477
- break
478
- }
479
-
480
- case CycleTypeEnum.小时: {
481
- // 不拓展的情况
482
- if (!copyType) {
483
- const targetCell = ensureCellExists(acc, rowNum, colNum)
484
- // 默认当前用户的班组和班次
485
- if (defaultShift) {
486
- targetCell.custom = {
487
- ...customData,
488
- teamData,
489
- businessDate: dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
490
- }
491
- break
492
- }
493
- targetCell.custom = {
494
- ...customData,
495
- businessDate: dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
496
- }
497
- break
498
- }
499
- copyNum = getDiffNum(teamData?.startDatetime, teamData?.endDatetime, dateTypeEnum.hour)
500
- for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
501
- const index = i * (copyInterval + 1)
502
- const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
503
- const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
504
- const targetCell = ensureCellExists(acc, newRowNum, newColNum)
505
- if (defaultShift) {
506
- const laterOneHour = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
507
- targetCell.custom = {
508
- ...customData,
509
- teamData,
510
- businessDate: generateTime(laterOneHour, dateTypeEnum.hour, i, timeIncrement)
511
- }
512
- continue
513
- }
514
- targetCell.custom = {
515
- ...customData,
516
- businessDate: generateTime(
517
- dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss'),
518
- dateTypeEnum.hour,
519
- i,
520
- timeIncrement
521
- )
522
- }
523
- }
524
- break
525
- }
526
- }
527
- }
528
-
529
- return acc
530
- }, {})
531
-
532
- return Promise.resolve(result)
533
- }
@@ -1,18 +0,0 @@
1
- import { generateUUID } from '@/utils'
2
- import { IWorkbookData, IWorksheetData, ICellData, LocaleType } from '@univerjs/presets'
3
-
4
- export type UseDataType = {
5
- workbookData: IWorkbookData
6
- id?: string
7
- name?: string
8
- appVersion?: string
9
- }
10
- export function useData(data: UseDataType): IWorkbookData {
11
-
12
- return {
13
- ...data?.workbookData,
14
- id: data?.id || generateUUID(),
15
- name: data?.name || '未命名',
16
- appVersion: data?.appVersion || '1.0.0',
17
- }
18
- }
@@ -1,22 +0,0 @@
1
- // 导出数据类型和方法
2
- export { useData } from './data'
3
- export type { UseDataType } from './data'
4
-
5
- // 导出数据枚举、类型和方法
6
- export {
7
- ModeEnum,
8
- CycleTypeEnum,
9
- initDateRange,
10
- filterIndicatorsCell,
11
- generateIndicatorsCells,
12
- } from './UniverSheet.data'
13
- export type {
14
- UniverSheetsProps,
15
- IGenerateIndicatorsCellsParams,
16
- TeamDataType,
17
- } from './UniverSheet.data'
18
-
19
- export {
20
- getNumColumns,
21
- mergeCellData
22
- } from './Methods.data'
package/src/index.ts DELETED
@@ -1,31 +0,0 @@
1
- // src/index.ts
2
- export { useData } from './components/UniverSheet'
3
- export type { UseDataType } from './components/UniverSheet'
4
-
5
- export {
6
- ModeEnum,
7
- CycleTypeEnum,
8
- } from './components/UniverSheet'
9
-
10
-
11
- export type {
12
- UniverSheetsProps,
13
- IGenerateIndicatorsCellsParams,
14
- TeamDataType,
15
- } from './components/UniverSheet'
16
-
17
- export {
18
- initDateRange,
19
- filterIndicatorsCell,
20
- generateIndicatorsCells,
21
- mergeCellData,
22
- getNumColumns
23
- } from './components/UniverSheet'
24
-
25
- export { decimal } from './utils/decimal'
26
-
27
- export { handleClearInput, generateUUID } from './utils'
28
-
29
-
30
- // 导出样式文件路径(不导入,让使用者自己导入)
31
- export const stylePath = './style.css'
package/src/main.ts DELETED
@@ -1,10 +0,0 @@
1
-
2
- import { createApp } from 'vue'
3
- import App from './App.vue'
4
- // import './style'
5
-
6
- // 开发环境引入 element-plus 样式
7
- // import 'element-plus/dist/index.css'
8
-
9
-
10
- createApp(App).mount('#app')
@@ -1,98 +0,0 @@
1
- import Decimal from 'decimal.js'
2
-
3
- class DecimalChain {
4
- private value: Decimal
5
-
6
- constructor(value: string | number | Decimal) {
7
- this.value = new Decimal(value)
8
- }
9
-
10
- /**
11
- * 加法运算
12
- * @param num 要加的数
13
- * @returns DecimalChain 实例,支持链式调用
14
- */
15
- add(num: string | number | Decimal): DecimalChain {
16
- this.value = this.value.add(num || 0)
17
- return this
18
- }
19
-
20
- /**
21
- * 减法运算
22
- * @param num 要减的数
23
- * @returns DecimalChain 实例,支持链式调用
24
- */
25
- subtract(num: string | number | Decimal): DecimalChain {
26
- this.value = this.value.sub(num || 0)
27
- return this
28
- }
29
-
30
- /**
31
- * 乘法运算
32
- * @param num 要乘的数
33
- * @returns DecimalChain 实例,支持链式调用
34
- */
35
- multiply(num: string | number | Decimal): DecimalChain {
36
- this.value = this.value.mul(num || 0)
37
- return this
38
- }
39
-
40
- /**
41
- * 除法运算
42
- * @param num 要除的数
43
- * @returns DecimalChain 实例,支持链式调用
44
- * @throws 当除数为0时抛出错误
45
- */
46
- divide(num: string | number | Decimal): DecimalChain {
47
- const divisor = new Decimal(num)
48
- if (divisor.isZero()) {
49
- throw new Error('除数是0')
50
- }
51
- this.value = this.value.div(divisor)
52
- return this
53
- }
54
-
55
- /**
56
- * 保留小数位数
57
- * @param dp 保留的小数位数
58
- * @param rounding 舍入模式,默认为四舍五入
59
- * @returns DecimalChain 实例,支持链式调用
60
- */
61
- toFixed(dp: number, rounding?: Decimal.Rounding): DecimalChain {
62
- this.value = new Decimal(this.value.toFixed(dp, rounding!))
63
- return this
64
- }
65
-
66
- /**
67
- * 返回当前值
68
- * @returns Decimal 实例
69
- */
70
- valueOf(): Decimal {
71
- return this.value
72
- }
73
-
74
- /**
75
- * 转换为字符串
76
- * @returns 字符串表示
77
- */
78
- toString(): string {
79
- return this.value.toString()
80
- }
81
-
82
- /**
83
- * 转换为数字
84
- * @returns 数字表示
85
- */
86
- toNumber(): number {
87
- return this.value.toNumber()
88
- }
89
- }
90
-
91
- /**
92
- * 创建一个支持链式调用的 Decimal 实例
93
- * @param value 初始值
94
- * * @returns DecimalChain 实例
95
- */
96
- export function decimal(value: string | number | Decimal = 0): DecimalChain {
97
- return new DecimalChain(value)
98
- }
@@ -1,33 +0,0 @@
1
-
2
- export const handleClearInput = (model: any, strList: string[]) => {
3
- for (const str of strList) {
4
- model[str] = null
5
- }
6
- }
7
- export const generateUUID = () => {
8
- if (typeof crypto === 'object') {
9
- if (typeof crypto.randomUUID === 'function') {
10
- return crypto.randomUUID()
11
- }
12
- if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
13
- const callback = (c: any) => {
14
- const num = Number(c)
15
- return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16)
16
- }
17
- return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, callback)
18
- }
19
- }
20
- let timestamp = new Date().getTime()
21
- let performanceNow = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0
22
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
23
- let random = Math.random() * 16
24
- if (timestamp > 0) {
25
- random = (timestamp + random) % 16 | 0
26
- timestamp = Math.floor(timestamp / 16)
27
- } else {
28
- random = (performanceNow + random) % 16 | 0
29
- performanceNow = Math.floor(performanceNow / 16)
30
- }
31
- return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16)
32
- })
33
- }
package/src/utils/is.ts DELETED
@@ -1,168 +0,0 @@
1
- // copy to vben-admin
2
-
3
- const toString = Object.prototype.toString
4
-
5
- export const is = (val: unknown, type: string) => {
6
- return toString.call(val) === `[object ${type}]`
7
- }
8
-
9
- export const isDef = <T = unknown>(val?: T): val is T => {
10
- return typeof val !== 'undefined'
11
- }
12
-
13
- export const isUnDef = <T = unknown>(val?: T): val is T => {
14
- return !isDef(val)
15
- }
16
-
17
- export const isObject = (val: any): val is Record<any, any> => {
18
- return val !== null && is(val, 'Object')
19
- }
20
-
21
- export const isEmpty = (val: any): boolean => {
22
- if (val === null || val === undefined || typeof val === 'undefined') {
23
- return true
24
- }
25
- if (isArray(val) || isString(val)) {
26
- return val.length === 0
27
- }
28
-
29
- if (val instanceof Map || val instanceof Set) {
30
- return val.size === 0
31
- }
32
-
33
- if (isObject(val)) {
34
- return Object.keys(val).length === 0
35
- }
36
-
37
- return false
38
- }
39
-
40
- export const isDate = (val: unknown): val is Date => {
41
- return is(val, 'Date')
42
- }
43
-
44
- export const isNull = (val: unknown): val is null => {
45
- return val === null
46
- }
47
-
48
- export const isNullAndUnDef = (val: unknown): val is null | undefined => {
49
- return isUnDef(val) && isNull(val)
50
- }
51
-
52
- export const isNullOrUnDef = (val: unknown): val is null | undefined => {
53
- return isUnDef(val) || isNull(val)
54
- }
55
-
56
- export const isNumber = (val: unknown): val is number => {
57
- return is(val, 'Number')
58
- }
59
-
60
- export const isPromise = <T = any>(val: unknown): val is Promise<T> => {
61
- return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch)
62
- }
63
-
64
- export const isString = (val: unknown): val is string => {
65
- return is(val, 'String')
66
- }
67
-
68
- export const isFunction = (val: unknown): val is Function => {
69
- return typeof val === 'function'
70
- }
71
-
72
- export const isBoolean = (val: unknown): val is boolean => {
73
- return is(val, 'Boolean')
74
- }
75
-
76
- export const isRegExp = (val: unknown): val is RegExp => {
77
- return is(val, 'RegExp')
78
- }
79
-
80
- export const isArray = (val: any): val is Array<any> => {
81
- return val && Array.isArray(val)
82
- }
83
-
84
- export const isWindow = (val: any): val is Window => {
85
- return typeof window !== 'undefined' && is(val, 'Window')
86
- }
87
-
88
- export const isElement = (val: unknown): val is Element => {
89
- return isObject(val) && !!val.tagName
90
- }
91
-
92
- export const isMap = (val: unknown): val is Map<any, any> => {
93
- return is(val, 'Map')
94
- }
95
-
96
- export const isServer = typeof window === 'undefined'
97
-
98
- export const isClient = !isServer
99
-
100
- export const isUrl = (path: string): boolean => {
101
- // fix:修复hash路由无法跳转的问题
102
- const reg =
103
- /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%#\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/
104
- return reg.test(path)
105
- }
106
-
107
- export const isDark = (): boolean => {
108
- return window.matchMedia('(prefers-color-scheme: dark)').matches
109
- }
110
-
111
- // 是否是图片链接
112
- export const isImgPath = (path: string): boolean => {
113
- return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path)
114
- }
115
-
116
- // 密码复杂度校验:至少包含大写字母、小写字母、数字、特殊字符中的三种
117
- export const isPasswordComplex = (value: string): boolean => {
118
- if (!isString(value)) {
119
- return false
120
- }
121
- let categories = 0
122
- if (/[A-Z]/.test(value)) {
123
- categories += 1
124
- }
125
- if (/[a-z]/.test(value)) {
126
- categories += 1
127
- }
128
- if (/[0-9]/.test(value)) {
129
- categories += 1
130
- }
131
- if (/[^A-Za-z0-9]/.test(value)) {
132
- categories += 1
133
- }
134
- return categories >= 3
135
- }
136
-
137
- // 密码校验:长度 6-20 位并满足复杂度
138
- export const isValidPassword = (value: string): boolean => {
139
- if (!isString(value)) {
140
- return false
141
- }
142
- const length = value.length
143
- if (length < 6 || length > 20) {
144
- return false
145
- }
146
- return isPasswordComplex(value)
147
- }
148
-
149
- export const isEmptyVal = (val: any): boolean => {
150
- return val === '' || val === null || val === undefined
151
- }
152
-
153
- export const isContainsChinese = (val: string): boolean => {
154
- // Chinese character Unicode range: \u4e00-\u9fff
155
- const chineseRegex = /[\u4e00-\u9fff]/
156
- return chineseRegex.test(val)
157
- }
158
-
159
- /**
160
- * @description 判断是否为windows环境
161
- * @returns
162
- */
163
- // export function isWindows(): boolean {
164
- // return (
165
- // (navigator?.userAgentData && navigator?.userAgentData?.platform === 'Windows') ||
166
- // navigator.platform === 'Win32'
167
- // )
168
- // }