tor-univer-sheet 1.0.0

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 (79) hide show
  1. package/README.md +2 -0
  2. package/dist/App.vue.d.ts +2 -0
  3. package/dist/components/ContentWrap/index.d.ts +2 -0
  4. package/dist/components/ContentWrap/src/ContentWrap.vue.d.ts +57 -0
  5. package/dist/components/Form/src/componentMap.d.ts +4 -0
  6. package/dist/components/Form/src/components/InputNumberWrapper.vue.d.ts +2 -0
  7. package/dist/components/Form/src/types.d.ts +16 -0
  8. package/dist/components/GlobalLoading/GlobalLoading.vue.d.ts +8 -0
  9. package/dist/components/GlobalLoading/index.d.ts +7 -0
  10. package/dist/components/IndicatorPointSelect/IndicatorPointSelect.vue.d.ts +2 -0
  11. package/dist/components/UniverSheet/UniverSheet.data.d.ts +23 -0
  12. package/dist/components/UniverSheet/UniverSheet.vue.d.ts +515 -0
  13. package/dist/components/UniverSheet/data.d.ts +9 -0
  14. package/dist/components/UniverSheet/plugins/Plugins.d.ts +29 -0
  15. package/dist/components/UniverSheet/plugins/importFile/ImportFileIcon.vue.d.ts +2 -0
  16. package/dist/components/UniverSheet/plugins/importFile/ImportFilePlugin.d.ts +14 -0
  17. package/dist/components/UniverSheet/plugins/index.d.ts +2 -0
  18. package/dist/components/UniverSheet/plugins/indicatorsContextMenu/IndicatorsContextMenuPlugin.d.ts +16 -0
  19. package/dist/components/UniverSheet/plugins/indicatorsContextMenu/components/IndicatorsMenu.vue.d.ts +2 -0
  20. package/dist/components/UniverSheet/plugins/indicatorsContextMenu/components/IndicatorsUniverSheetConfigDialog.vue.d.ts +234 -0
  21. package/dist/components/UniverSheet/plugins/saveButton/ButtonIcon.vue.d.ts +2 -0
  22. package/dist/components/UniverSheet/plugins/saveButton/SaveButton.d.ts +14 -0
  23. package/dist/components/UniverSheet/plugins/syncContextMenu/SyncContextMenu.vue.d.ts +2 -0
  24. package/dist/components/UniverSheet/plugins/syncContextMenu/SyncContextMenuPlugin.d.ts +14 -0
  25. package/dist/components/UniverSheet/plugins/timeConfigContextMenu/TimeConfigContextMenuPlugin.d.ts +16 -0
  26. package/dist/components/UniverSheet/plugins/timeConfigContextMenu/components/TimeConfigMenu.vue.d.ts +2 -0
  27. package/dist/components/UniverSheet/plugins/timeConfigContextMenu/components/TimeConfigUniverSheetConfigDialog.vue.d.ts +234 -0
  28. package/dist/favicon.ico +0 -0
  29. package/dist/hooks/useMessage.d.ts +18 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/main.d.ts +0 -0
  32. package/dist/tor-univer-sheet.es.js +213 -0
  33. package/dist/tor-univer-sheet.umd.js +1 -0
  34. package/dist/types/components.d.ts +52 -0
  35. package/dist/types/external-components.d.ts +14 -0
  36. package/dist/types/form.d.ts +51 -0
  37. package/dist/utils/decimal.d.ts +59 -0
  38. package/dist/utils/fileHelp.d.ts +8 -0
  39. package/dist/utils/index.d.ts +2 -0
  40. package/dist/utils/is.d.ts +33 -0
  41. package/dist/utils/propTypes.d.ts +10 -0
  42. package/package.json +88 -0
  43. package/src/App.vue +16 -0
  44. package/src/components/ContentWrap/index.ts +3 -0
  45. package/src/components/ContentWrap/src/ContentWrap.vue +50 -0
  46. package/src/components/Form/src/componentMap.ts +51 -0
  47. package/src/components/Form/src/components/InputNumberWrapper.vue +12 -0
  48. package/src/components/Form/src/types.ts +18 -0
  49. package/src/components/GlobalLoading/GlobalLoading.vue +89 -0
  50. package/src/components/GlobalLoading/index.ts +45 -0
  51. package/src/components/IndicatorPointSelect/IndicatorPointSelect.vue +9 -0
  52. package/src/components/UniverSheet/UniverSheet.data.ts +521 -0
  53. package/src/components/UniverSheet/UniverSheet.vue +339 -0
  54. package/src/components/UniverSheet/data.ts +18 -0
  55. package/src/components/UniverSheet/plugins/Plugins.ts +246 -0
  56. package/src/components/UniverSheet/plugins/importFile/ImportFileIcon.vue +26 -0
  57. package/src/components/UniverSheet/plugins/importFile/ImportFilePlugin.ts +109 -0
  58. package/src/components/UniverSheet/plugins/index.ts +10 -0
  59. package/src/components/UniverSheet/plugins/indicatorsContextMenu/IndicatorsContextMenuPlugin.ts +134 -0
  60. package/src/components/UniverSheet/plugins/indicatorsContextMenu/components/IndicatorsMenu.vue +49 -0
  61. package/src/components/UniverSheet/plugins/indicatorsContextMenu/components/IndicatorsUniverSheetConfigDialog.vue +153 -0
  62. package/src/components/UniverSheet/plugins/saveButton/ButtonIcon.vue +19 -0
  63. package/src/components/UniverSheet/plugins/saveButton/SaveButton.ts +68 -0
  64. package/src/components/UniverSheet/plugins/syncContextMenu/SyncContextMenu.vue +24 -0
  65. package/src/components/UniverSheet/plugins/syncContextMenu/SyncContextMenuPlugin.ts +65 -0
  66. package/src/components/UniverSheet/plugins/timeConfigContextMenu/TimeConfigContextMenuPlugin.ts +133 -0
  67. package/src/components/UniverSheet/plugins/timeConfigContextMenu/components/TimeConfigMenu.vue +10 -0
  68. package/src/components/UniverSheet/plugins/timeConfigContextMenu/components/TimeConfigUniverSheetConfigDialog.vue +152 -0
  69. package/src/hooks/useMessage.ts +93 -0
  70. package/src/index.ts +10 -0
  71. package/src/main.ts +14 -0
  72. package/src/types/components.d.ts +52 -0
  73. package/src/types/external-components.d.ts +16 -0
  74. package/src/types/form.d.ts +52 -0
  75. package/src/utils/decimal.ts +98 -0
  76. package/src/utils/fileHelp.ts +71 -0
  77. package/src/utils/index.ts +32 -0
  78. package/src/utils/is.ts +168 -0
  79. package/src/utils/propTypes.ts +24 -0
@@ -0,0 +1,18 @@
1
+ import { FormSchema } from '@/types/form'
2
+
3
+ export interface PlaceholderModel {
4
+ placeholder?: string
5
+ startPlaceholder?: string
6
+ endPlaceholder?: string
7
+ rangeSeparator?: string
8
+ }
9
+
10
+ export type FormProps = {
11
+ schema?: FormSchema[]
12
+ isCol?: boolean
13
+ model?: Recordable
14
+ autoSetPlaceholder?: boolean
15
+ isCustom?: boolean
16
+ labelWidth?: string | number
17
+ fieldMapToTime?: [string, [string, string], string][] // [目标字段, [开始字段, 结束字段], 日期格式][]
18
+ } & Recordable
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <div v-if="visible" class="global-loading" :style="{ backgroundColor }">
3
+ <div class="loading-content">
4
+ <div class="loader">
5
+ <span></span>
6
+ <span></span>
7
+ <span></span>
8
+ </div>
9
+ <div v-if="tip" class="loading-text">{{ tip }}</div>
10
+ </div>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { ref, computed } from 'vue'
16
+
17
+ const props = defineProps<{
18
+ tip?: string
19
+ size?: 'small' | 'default' | 'large'
20
+ backgroundColor?: string
21
+ visible?: boolean
22
+ }>()
23
+ </script>
24
+
25
+ <style scoped>
26
+ .global-loading {
27
+ position: fixed;
28
+ top: 0;
29
+ left: 0;
30
+ right: 0;
31
+ bottom: 0;
32
+ z-index: 10000;
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ background: rgba(122, 122, 122, 0.8);
37
+ }
38
+ .loading-content {
39
+ display: flex;
40
+ flex-direction: column;
41
+ align-items: center;
42
+ }
43
+ .loading-text {
44
+ color: #fff;
45
+ font-size: 14px;
46
+ }
47
+
48
+ .loader {
49
+ width: 100px;
50
+ height: 100px;
51
+ border-radius: 100%;
52
+ position: relative;
53
+ margin: 0 auto;
54
+ span {
55
+ display: inline-block;
56
+ width: 20px;
57
+ height: 20px;
58
+ border-radius: 100%;
59
+ background-color: #3498db;
60
+ margin: 35px 5px;
61
+ &:nth-child(1) {
62
+ animation: bounce 1s ease-in-out infinite;
63
+ }
64
+ &:nth-child(2) {
65
+ animation: bounce 1s ease-in-out 0.33s infinite;
66
+ }
67
+ &:nth-child(3) {
68
+ animation: bounce 1s ease-in-out 0.66s infinite;
69
+ }
70
+ @keyframes bounce {
71
+ 0%,
72
+ 75%,
73
+ 100% {
74
+ -webkit-transform: translateY(0);
75
+ -ms-transform: translateY(0);
76
+ -o-transform: translateY(0);
77
+ transform: translateY(0);
78
+ }
79
+
80
+ 25% {
81
+ -webkit-transform: translateY(-20px);
82
+ -ms-transform: translateY(-20px);
83
+ -o-transform: translateY(-20px);
84
+ transform: translateY(-20px);
85
+ }
86
+ }
87
+ }
88
+ }
89
+ </style>
@@ -0,0 +1,45 @@
1
+ import { createVNode, render, reactive } from 'vue'
2
+ import GlobalLoading from './GlobalLoading.vue'
3
+
4
+ let vm: any = null
5
+ let container: HTMLDivElement | null = null
6
+
7
+ const state = reactive({
8
+ visible: false,
9
+ tip: '加载中...',
10
+ size: 'large',
11
+ backgroundColor: 'rgba(0,0,0,0.7)'
12
+ })
13
+
14
+ function openLoading(tip = '加载中...', size: 'small' | 'default' | 'large' = 'large', backgroundColor = 'rgba(0,0,0,0.7)') {
15
+ state.tip = tip
16
+ state.size = size
17
+ state.backgroundColor = backgroundColor
18
+ state.visible = true
19
+
20
+ if (!container) {
21
+ container = document.createElement('div')
22
+ document.body.appendChild(container)
23
+ }
24
+ if (!vm) {
25
+ vm = createVNode(GlobalLoading, state)
26
+ render(vm, container)
27
+ }
28
+ }
29
+
30
+ function closeLoading() {
31
+ state.visible = false
32
+ setTimeout(() => {
33
+ if (container) {
34
+ render(null, container)
35
+ document.body.removeChild(container)
36
+ container = null
37
+ vm = null
38
+ }
39
+ }, 300)
40
+ }
41
+
42
+ export const globalLoading = {
43
+ openLoading,
44
+ closeLoading
45
+ }
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <ElInput v-model="modelValue" />
3
+ </template>
4
+ <script lang="ts" setup>
5
+ import { ref } from 'vue'
6
+ import { ElInput } from 'element-plus'
7
+
8
+ const modelValue = ref('')
9
+ </script>
@@ -0,0 +1,521 @@
1
+ import { isArray, isEmpty } from '@/utils/is'
2
+ import { CycleTypeEnum } from './plugins/Plugins'
3
+ import dayjs from 'dayjs'
4
+ import { ICellData, IWorksheetData, IObjectMatrixPrimitiveType, CellValueType } from '@univerjs/presets'
5
+ import { decimal } from '@/utils/decimal'
6
+
7
+ export enum ModeEnum {
8
+ view = 'view',
9
+ edit = 'edit'
10
+ }
11
+
12
+ export interface UniverSheetsProps {
13
+ mode: ModeEnum
14
+ showImportFilePlugin?: boolean
15
+ showIndicatorsContextMenuPlugin?: boolean
16
+ showSyncContextMenuPlugin?: boolean
17
+ showTimeConfigContextMenuPlugin?: boolean
18
+ license: string
19
+ }
20
+
21
+ export async function initDateRange(cycleType: CycleTypeEnum, date: string[] | string): Promise<string[]> {
22
+ if (!date) return Promise.reject('日期不能为空')
23
+ switch (cycleType) {
24
+ case CycleTypeEnum.年:
25
+ if (isArray(date)) {
26
+ return Promise.resolve(date)
27
+ }
28
+ const parsedYearDate = dayjs(date)
29
+ if (!parsedYearDate.isValid()) {
30
+ return Promise.reject('无效的日期格式')
31
+ }
32
+ const year = parsedYearDate.year()
33
+ const startMonth = `${year}-01`
34
+ const endMonth = `${year}-12`
35
+
36
+ return Promise.resolve([startMonth, endMonth])
37
+ case CycleTypeEnum.月:
38
+ if (isArray(date)) {
39
+ return Promise.resolve(date)
40
+ }
41
+ const parsedMonthDate = dayjs(date)
42
+ if (!parsedMonthDate.isValid()) {
43
+ return Promise.reject('无效的日期格式')
44
+ }
45
+ const monthStartDate = parsedMonthDate.startOf('month').format('YYYY-MM-DD')
46
+ const monthEndDate = parsedMonthDate.endOf('month').format('YYYY-MM-DD')
47
+
48
+ return Promise.resolve([monthStartDate, monthEndDate])
49
+ case CycleTypeEnum.天:
50
+ if (isArray(date)) {
51
+ return Promise.resolve(date)
52
+ }
53
+ const parsedDayDate = dayjs(date)
54
+ if (!parsedDayDate.isValid()) {
55
+ return Promise.reject('无效的日期格式')
56
+ }
57
+ const startOfDay = parsedDayDate.startOf('day').format('YYYY-MM-DD HH:mm:ss')
58
+ const endOfDay = parsedDayDate.endOf('day').format('YYYY-MM-DD HH:mm:ss')
59
+ return Promise.resolve([startOfDay, endOfDay])
60
+ default:
61
+ return Promise.reject('不支持的周期类型')
62
+ }
63
+ }
64
+
65
+ enum dateTypeEnum {
66
+ year = 'year',
67
+ month = 'month',
68
+ day = 'day',
69
+ hour = 'hour'
70
+ }
71
+
72
+ function getDiffNum(startDate, endDate, dateType: dateTypeEnum) {
73
+ if (!dateType) return 0
74
+ const format = {
75
+ year: 'YYYY',
76
+ month: 'YYYY-MM',
77
+ day: 'YYYY-MM-DD',
78
+ hour: 'HH:mm:ss'
79
+ }[dateType]
80
+ if (['day', 'hour'].includes(dateType)) {
81
+ return dayjs(endDate, format).diff(dayjs(startDate, format), dateType) + 1
82
+ }
83
+ return dayjs(endDate, format).diff(dayjs(startDate, format), dateType)
84
+ }
85
+
86
+ function getForwardPushTimes(startDate: string, forwardPushTime: number, dateType: dateTypeEnum): string {
87
+ if (!dateType) {
88
+ throw new Error('日期类型不能为空')
89
+ }
90
+ const format = {
91
+ year: 'YYYY',
92
+ month: 'YYYY-MM',
93
+ day: 'YYYY-MM-DD',
94
+ hour: 'HH:mm:ss'
95
+ }[dateType]
96
+ return dayjs(startDate).subtract(forwardPushTime, dateType).format(format)
97
+ }
98
+
99
+ function generateTime(base, type, num, times) {
100
+ const format = {
101
+ year: 'YYYY',
102
+ month: 'YYYY-MM',
103
+ day: 'YYYY-MM-DD',
104
+ hour: 'YYYY-MM-DD HH:mm:ss'
105
+ }[type]
106
+ return dayjs(base, format)
107
+ .add(num * times, type)
108
+ .format(format)
109
+ }
110
+
111
+ interface IGenerateIndicatorsCellsParams {
112
+ extraArgs: Recordable
113
+ rangeData: string[]
114
+ currentDay?: string
115
+ }
116
+
117
+ type TeamDataType = {
118
+ teamId: string // 班组id
119
+ teamName: string // 班组名称
120
+ shiftId: string // 班次id
121
+ shiftName: string // 班次名称
122
+ scheduleConfigName: string // 排班配置名称
123
+ scheduleConfigId: string // 排班配置ID
124
+ workName: string // 作业名称
125
+ workCoding: string // 作业编码
126
+ startDatetime: string // 开始时间
127
+ endDatetime: string // 结束时间
128
+ }
129
+
130
+ function ensureCellExists(acc: any, rowNum: string | number, colNum: string | number): any {
131
+ // 确保 acc[rowNum] 存在
132
+ if (!acc[rowNum]) {
133
+ acc[rowNum] = {}
134
+ }
135
+
136
+ // 确保 acc[rowNum][colNum] 存在
137
+ if (!acc[rowNum][colNum]) {
138
+ acc[rowNum][colNum] = {}
139
+ }
140
+
141
+ return acc[rowNum][colNum]
142
+ }
143
+
144
+ export async function filterIndicatorsCell(cellData: IObjectMatrixPrimitiveType<ICellData>) {
145
+ if (!cellData) {
146
+ throw new Error('cellData is required')
147
+ }
148
+ const result = Object.entries(cellData).reduce((acc, cur: any) => {
149
+ const [rowNum, cols] = cur
150
+ for (const [colNum, cellData] of Object.entries(cols)) {
151
+ const { custom, v } = cellData as ICellData
152
+ if (!custom) continue
153
+ const { cellType } = custom
154
+ if (cellType === 'indicator') {
155
+ const targetCell = ensureCellExists(acc, rowNum, colNum)
156
+ targetCell.custom = custom
157
+ targetCell.v = v
158
+ }
159
+ }
160
+ return acc
161
+ }, {})
162
+ if (!result || isEmpty(result)) {
163
+ return Promise.reject(new Error('No data found'))
164
+ }
165
+ return Promise.resolve(result)
166
+ }
167
+
168
+ function createTimeCells({
169
+ acc,
170
+ params,
171
+ initRowNum,
172
+ initColNum,
173
+ cellData
174
+ }: {
175
+ acc: any
176
+ params: IGenerateIndicatorsCellsParams
177
+ initRowNum: number
178
+ initColNum: number
179
+ cellData: any
180
+ }) {
181
+ const { rangeData, currentDay, extraArgs } = params
182
+ const teamData: any = extraArgs?.teamData || {}
183
+ const { cycleType, timeIncrement, forwardPush, copyType, copyInterval, defaultShift } = cellData.custom as Recordable
184
+
185
+ // 计算生成的行、列数量
186
+ let copyNum = 0
187
+
188
+ switch (cycleType) {
189
+ case CycleTypeEnum.天: {
190
+ let forwardServenDay: string = ''
191
+ if (forwardPush) {
192
+ forwardServenDay = getForwardPushTimes(rangeData[0], 6, dateTypeEnum.day)
193
+ }
194
+
195
+ // 不拓展的情况
196
+ if (!copyType) {
197
+ let businessDate: string = ''
198
+ if (forwardPush) {
199
+ businessDate = forwardServenDay
200
+ } else {
201
+ businessDate = rangeData[0]
202
+ }
203
+
204
+ // 使用封装方法确保结构存在
205
+ const targetCell = ensureCellExists(acc, initRowNum, initColNum)
206
+ targetCell.v = businessDate
207
+ targetCell.t = CellValueType.STRING
208
+ break
209
+ }
210
+
211
+ // 拓展的情况
212
+ if (forwardPush) {
213
+ copyNum = getDiffNum(forwardServenDay, rangeData[0], dateTypeEnum.day)
214
+ } else {
215
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.day)
216
+ }
217
+
218
+ // 向右增加列,向下增加行
219
+ for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
220
+ // 处理跨行跨列
221
+ const index = i * (copyInterval + 1)
222
+ let businessDate: string = ''
223
+ if (forwardPush) {
224
+ businessDate = generateTime(forwardServenDay, dateTypeEnum.day, i, timeIncrement)
225
+ } else {
226
+ businessDate = generateTime(rangeData[0], dateTypeEnum.day, i, timeIncrement)
227
+ }
228
+
229
+ const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
230
+ const newColNum = copyType === 'right' ? initColNum + index : initColNum
231
+
232
+ // 使用封装方法确保新位置结构存在
233
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
234
+ targetCell.v = businessDate
235
+ targetCell.t = CellValueType.STRING
236
+ }
237
+ break
238
+ }
239
+
240
+ case CycleTypeEnum.月: {
241
+ // 不拓展的情况
242
+ if (!copyType) {
243
+ const targetCell = ensureCellExists(acc, initRowNum, initColNum)
244
+ targetCell.v = rangeData[0]
245
+ targetCell.t = CellValueType.STRING
246
+ break
247
+ }
248
+
249
+ // 向右增加列,向下增加行
250
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.month)
251
+ for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
252
+ // 处理跨行跨列
253
+ const index = i * (copyInterval + 1)
254
+ const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
255
+ const newColNum = copyType === 'right' ? initColNum + index : initColNum
256
+
257
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
258
+ targetCell.v = generateTime(rangeData[0], dateTypeEnum.month, i, timeIncrement)
259
+ targetCell.t = CellValueType.STRING
260
+ }
261
+ break
262
+ }
263
+
264
+ case CycleTypeEnum.年: {
265
+ // 不拓展的情况
266
+ if (!copyType) {
267
+ const targetCell = ensureCellExists(acc, initRowNum, initColNum)
268
+ targetCell.v = rangeData[0]
269
+ targetCell.t = CellValueType.STRING
270
+ break
271
+ }
272
+
273
+ // 向右增加列,向下增加行
274
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.year)
275
+ for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
276
+ // 处理跨行跨列
277
+ const index = i * (copyInterval + 1)
278
+ const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
279
+ const newColNum = copyType === 'right' ? initColNum + index : initColNum
280
+
281
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
282
+ targetCell.v = generateTime(rangeData[0], dateTypeEnum.year, i, timeIncrement)
283
+ targetCell.t = CellValueType.STRING
284
+ }
285
+ break
286
+ }
287
+ case CycleTypeEnum.小时: {
288
+ if (!copyType) {
289
+ const targetCell = ensureCellExists(acc, initRowNum, initColNum)
290
+ targetCell.t = CellValueType.STRING
291
+ if (defaultShift) {
292
+ targetCell.v = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
293
+ break
294
+ }
295
+ targetCell.v = dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
296
+ break
297
+ }
298
+ copyNum = getDiffNum(teamData?.startDatetime, teamData?.endDatetime, dateTypeEnum.hour)
299
+ for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
300
+ // 处理跨行跨列
301
+ const index = i * (copyInterval + 1)
302
+ const newRowNum = copyType === 'right' ? initRowNum : initRowNum + index
303
+ const newColNum = copyType === 'right' ? initColNum + index : initColNum
304
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
305
+ targetCell.t = CellValueType.STRING
306
+ if (defaultShift) {
307
+ const laterOneHour = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
308
+ targetCell.v = generateTime(laterOneHour, dateTypeEnum.hour, i, timeIncrement)
309
+ continue
310
+ }
311
+ targetCell.v = generateTime(dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss'), dateTypeEnum.hour, i, timeIncrement)
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ export async function generateIndicatorsCells(
318
+ cells: IObjectMatrixPrimitiveType<ICellData>,
319
+ params: IGenerateIndicatorsCellsParams
320
+ ): Promise<ICellData> {
321
+ if (!cells) {
322
+ return Promise.reject('没有可用的单元格数据')
323
+ }
324
+
325
+ const { extraArgs, rangeData } = params
326
+ if (!rangeData.length) {
327
+ return Promise.reject('处理时间范围失败, rangeData不能为空')
328
+ }
329
+ const teamData: TeamDataType = extraArgs?.teamData || {}
330
+
331
+ const currentDay = params?.currentDay || dayjs().format('YYYY-MM-DD')
332
+
333
+ const result = Object.entries(cells).reduce((acc, cur) => {
334
+ const [rowNum, cols] = cur
335
+
336
+ for (const [colNum, cellData] of Object.entries(cols)) {
337
+ const { custom } = cellData as ICellData
338
+ if (!custom) continue
339
+
340
+ const { cellType, cycleType, timeIncrement, forwardPush, copyType, copyInterval, defaultShift } = custom as Recordable
341
+
342
+ if (cellType === 'time') {
343
+ createTimeCells({ acc, params, initRowNum: Number(rowNum), initColNum: Number(colNum), cellData })
344
+ continue
345
+ }
346
+
347
+ const customData = {
348
+ cycleType,
349
+ indicatorName: custom.indicatorName,
350
+ indicatorCode: custom.indicatorCode,
351
+ indicatorId: custom.indicatorId,
352
+ indicatorDimensionName: custom.indicatorDimensionName,
353
+ indicatorDimensionConfig: custom.indicatorDimensionConfig,
354
+ required: custom.required,
355
+ cellType: custom.cellType,
356
+ defaultShift: custom.defaultShift
357
+ }
358
+
359
+ let copyNum = 0
360
+ switch (cycleType) {
361
+ case CycleTypeEnum.天: {
362
+ let forwardServenDay: string = ''
363
+ if (forwardPush) {
364
+ forwardServenDay = getForwardPushTimes(rangeData[0], 6, dateTypeEnum.day)
365
+ }
366
+
367
+ if (!copyType) {
368
+ let businessDate: string = ''
369
+ if (forwardPush) {
370
+ businessDate = forwardServenDay
371
+ } else {
372
+ businessDate = rangeData[0]
373
+ }
374
+
375
+ // 使用封装方法确保结构存在
376
+ const targetCell = ensureCellExists(acc, rowNum, colNum)
377
+ targetCell.custom = {
378
+ ...customData,
379
+ businessDate
380
+ }
381
+ if (defaultShift) {
382
+ targetCell.custom.teamData = teamData
383
+ }
384
+ break
385
+ }
386
+
387
+ if (forwardPush) {
388
+ copyNum = getDiffNum(forwardServenDay, rangeData[0], dateTypeEnum.day)
389
+ } else {
390
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.day)
391
+ }
392
+
393
+ for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
394
+ const index = i * (copyInterval + 1)
395
+ let businessDate: string = ''
396
+ if (forwardPush) {
397
+ businessDate = generateTime(forwardServenDay, dateTypeEnum.day, i, timeIncrement)
398
+ } else {
399
+ businessDate = generateTime(rangeData[0], dateTypeEnum.day, i, timeIncrement)
400
+ }
401
+
402
+ const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
403
+ const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
404
+
405
+ // 使用封装方法确保新位置结构存在
406
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
407
+ targetCell.custom = {
408
+ ...customData,
409
+ businessDate
410
+ }
411
+ if (defaultShift) {
412
+ targetCell.custom.teamData = teamData
413
+ }
414
+ }
415
+ break
416
+ }
417
+
418
+ case CycleTypeEnum.月: {
419
+ if (!copyType) {
420
+ const targetCell = ensureCellExists(acc, rowNum, colNum)
421
+ targetCell.custom = {
422
+ ...customData,
423
+ businessDate: rangeData[0]
424
+ }
425
+ break
426
+ }
427
+
428
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.month)
429
+ for (let i = 0; i <= Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
430
+ const index = i * (copyInterval + 1)
431
+ const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
432
+ const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
433
+
434
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
435
+ targetCell.custom = {
436
+ ...customData,
437
+ businessDate: generateTime(rangeData[0], dateTypeEnum.month, i, timeIncrement)
438
+ }
439
+ }
440
+ break
441
+ }
442
+
443
+ case CycleTypeEnum.年: {
444
+ if (!copyType) {
445
+ const targetCell = ensureCellExists(acc, rowNum, colNum)
446
+ targetCell.custom = {
447
+ ...customData,
448
+ businessDate: rangeData[0]
449
+ }
450
+ break
451
+ }
452
+
453
+ copyNum = getDiffNum(rangeData[0], rangeData[1], dateTypeEnum.year)
454
+ for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
455
+ const index = i * (copyInterval + 1)
456
+ const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
457
+ const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
458
+
459
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
460
+ targetCell.custom = {
461
+ ...customData,
462
+ businessDate: generateTime(rangeData[0], dateTypeEnum.year, i, timeIncrement)
463
+ }
464
+ }
465
+ break
466
+ }
467
+
468
+ case CycleTypeEnum.小时: {
469
+ // 不拓展的情况
470
+ if (!copyType) {
471
+ const targetCell = ensureCellExists(acc, rowNum, colNum)
472
+ // 默认当前用户的班组和班次
473
+ if (defaultShift) {
474
+ targetCell.custom = {
475
+ ...customData,
476
+ teamData,
477
+ businessDate: dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
478
+ }
479
+ break
480
+ }
481
+ targetCell.custom = {
482
+ ...customData,
483
+ businessDate: dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
484
+ }
485
+ break
486
+ }
487
+ copyNum = getDiffNum(teamData?.startDatetime, teamData?.endDatetime, dateTypeEnum.hour)
488
+ for (let i = 0; i < Math.abs(copyNum === 0 ? 1 : copyNum); i++) {
489
+ const index = i * (copyInterval + 1)
490
+ const newRowNum = copyType === 'right' ? rowNum : decimal(rowNum).add(index).toNumber()
491
+ const newColNum = copyType === 'right' ? decimal(colNum).add(index).toNumber() : colNum
492
+ const targetCell = ensureCellExists(acc, newRowNum, newColNum)
493
+ if (defaultShift) {
494
+ const laterOneHour = dayjs(teamData?.startDatetime).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
495
+ targetCell.custom = {
496
+ ...customData,
497
+ teamData,
498
+ businessDate: generateTime(laterOneHour, dateTypeEnum.hour, i, timeIncrement)
499
+ }
500
+ continue
501
+ }
502
+ targetCell.custom = {
503
+ ...customData,
504
+ businessDate: generateTime(
505
+ dayjs(currentDay).add(1, 'hour').format('YYYY-MM-DD HH:mm:ss'),
506
+ dateTypeEnum.hour,
507
+ i,
508
+ timeIncrement
509
+ )
510
+ }
511
+ }
512
+ break
513
+ }
514
+ }
515
+ }
516
+
517
+ return acc
518
+ }, {})
519
+
520
+ return Promise.resolve(result)
521
+ }