uni-oaview 1.3.0 → 1.4.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.
@@ -0,0 +1,196 @@
1
+ <template>
2
+ <uni-collapse ref="collapseRef" v-model="activeNames">
3
+ <uni-collapse-item
4
+ v-for="meta in audioLogMetas"
5
+ :key="meta.id"
6
+ :title="meta.title"
7
+ :class="{
8
+ 'uni-collapse-item-error': meta.isError,
9
+ }"
10
+ >
11
+ <view style="font-size: 10px; padding: 10px 15px">
12
+ <view style="word-break: break-all; padding: 8px 0; margin-bottom: 10px">
13
+ <text :selectable="true" style="font-weight: bolder">实例ID:</text>
14
+ {{ meta.instanceId }}
15
+ </view>
16
+ <template v-if="isExpanded(meta.id)">
17
+ <view style="word-break: break-all; padding: 8px 0; margin-bottom: 10px">
18
+ <text :selectable="true" style="font-weight: bolder">音源:</text>
19
+ {{ meta.src || '-' }}
20
+ </view>
21
+ <view style="word-break: break-all; padding: 8px 0; margin-bottom: 10px">
22
+ <text :selectable="true" style="font-weight: bolder">时长:</text>
23
+ {{ meta.duration > 0 ? meta.duration.toFixed(2) : '-' }}s
24
+ </view>
25
+ <view style="word-break: break-all; padding: 8px 0; margin-bottom: 10px">
26
+ <text :selectable="true" style="font-weight: bolder">当前位置:</text>
27
+ {{ meta.currentTime.toFixed(2) }}s
28
+ </view>
29
+ <view style="word-break: break-all; padding: 8px 0; margin-bottom: 10px">
30
+ <text :selectable="true" style="font-weight: bolder">操作:</text>
31
+ {{ meta.action }}
32
+ </view>
33
+ <view style="word-break: break-all; padding: 8px 0">
34
+ <text :selectable="true" style="font-weight: bolder">详情:</text>
35
+ <awesome-display-info :log="getAudioLogDetail(meta.id)?.data" />
36
+ </view>
37
+ </template>
38
+ </view>
39
+ </uni-collapse-item>
40
+ </uni-collapse>
41
+ </template>
42
+
43
+ <script lang="ts" setup>
44
+ import { nextTick, onBeforeUnmount, ref, shallowRef } from 'vue';
45
+ import awesomeDisplayInfo from './awesome-display-info.vue';
46
+ import { audioSubject, getAudioLogs } from 'uniapp-log-sdk';
47
+
48
+ interface AudioLog {
49
+ id: number;
50
+ type: string;
51
+ src: string;
52
+ action: string;
53
+ data?: any;
54
+ timestamp: number;
55
+ duration: number;
56
+ currentTime: number;
57
+ paused: boolean;
58
+ }
59
+
60
+ interface AudioLogMeta {
61
+ id: string;
62
+ title: string;
63
+ instanceId: number;
64
+ src: string;
65
+ duration: number;
66
+ currentTime: number;
67
+ action: string;
68
+ isError: boolean;
69
+ }
70
+
71
+ const MAX_AUDIO_LOGS = 100;
72
+
73
+ const collapseRef = ref<{ resize?: () => void } | null>(null);
74
+ const activeNames = ref<string[] | string>([]);
75
+
76
+ const audioLogDetailMap = shallowRef<Map<string, AudioLog>>(new Map());
77
+ const audioLogMetas = ref<AudioLogMeta[]>([]);
78
+
79
+ const formatTime = (timestamp: number): string => {
80
+ const date = new Date(timestamp);
81
+ const year = date.getFullYear();
82
+ const month = String(date.getMonth() + 1).padStart(2, '0');
83
+ const day = String(date.getDate()).padStart(2, '0');
84
+ const hours = String(date.getHours()).padStart(2, '0');
85
+ const minutes = String(date.getMinutes()).padStart(2, '0');
86
+ const seconds = String(date.getSeconds()).padStart(2, '0');
87
+ const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
88
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
89
+ };
90
+
91
+ const buildAudioLogId = (log: AudioLog): string => {
92
+ return `${log.id}-${log.timestamp}`;
93
+ };
94
+
95
+ const buildMetaFromLog = (log: AudioLog): AudioLogMeta => {
96
+ const { id, src, duration, currentTime, action, timestamp, data } = log;
97
+ const timeStr = formatTime(timestamp);
98
+ const isError = action === 'error';
99
+ return {
100
+ id: buildAudioLogId(log),
101
+ title: `[${timeStr}] ${action} - ${src || '(未指定)'} [${duration > 0 ? duration.toFixed(2) : '-'}s]`,
102
+ instanceId: id,
103
+ src,
104
+ duration,
105
+ currentTime,
106
+ action,
107
+ isError,
108
+ };
109
+ };
110
+
111
+ const getActiveNameList = (): string[] => {
112
+ const value = activeNames.value;
113
+ return Array.isArray(value) ? value : value ? [value] : [];
114
+ };
115
+
116
+ const isExpanded = (id: string): boolean => getActiveNameList().includes(id);
117
+
118
+ const getAudioLogDetail = (id: string): AudioLog | null => {
119
+ return audioLogDetailMap.value.get(id) ?? null;
120
+ };
121
+
122
+ const upsertLogs = (logs: AudioLog[]) => {
123
+ const nextLogs = logs.slice(-MAX_AUDIO_LOGS);
124
+ const detailMap = audioLogDetailMap.value;
125
+
126
+ const nextMetas: AudioLogMeta[] = [];
127
+ for (const log of nextLogs) {
128
+ const id = buildAudioLogId(log);
129
+ detailMap.set(id, log);
130
+ nextMetas.push(buildMetaFromLog(log));
131
+ }
132
+
133
+ audioLogMetas.value = nextMetas;
134
+
135
+ // 清理 detailMap,避免无限增长
136
+ const keepIds = new Set(nextMetas.map((m) => m.id));
137
+ for (const key of detailMap.keys()) {
138
+ if (!keepIds.has(key)) detailMap.delete(key);
139
+ }
140
+
141
+ // 清理 activeNames(如果展开项已被裁剪掉)
142
+ const currentActive = activeNames.value;
143
+ if (Array.isArray(currentActive)) {
144
+ if (currentActive.length) activeNames.value = currentActive.filter((id) => keepIds.has(id));
145
+ } else if (currentActive && !keepIds.has(currentActive)) {
146
+ activeNames.value = '';
147
+ }
148
+ };
149
+
150
+ upsertLogs(getAudioLogs());
151
+
152
+ const stop = audioSubject.subscribe((data: AudioLog[]) => {
153
+ upsertLogs(data);
154
+ });
155
+
156
+ // 展开项变化时刷新 collapse 高度缓存(小程序端必须手动调用,否则内容高度可能为 0)
157
+ const unwatch = ref(() => {});
158
+ unwatch.value = (() => {
159
+ let lastActiveNames = getActiveNameList().join('|');
160
+ return () => {
161
+ const currentActiveNames = getActiveNameList().join('|');
162
+ if (currentActiveNames !== lastActiveNames) {
163
+ // #ifdef MP
164
+ nextTick(() => collapseRef.value?.resize?.());
165
+ // #endif
166
+ lastActiveNames = currentActiveNames;
167
+ }
168
+ };
169
+ })();
170
+
171
+ onBeforeUnmount(() => {
172
+ stop?.unsubscribe();
173
+ });
174
+ </script>
175
+
176
+ <style lang="scss" scoped>
177
+ .uni-collapse-content {
178
+ font-size: 12px;
179
+ }
180
+ ::v-deep {
181
+ .uni-collapse-item__title-text {
182
+ white-space: normal !important;
183
+ overflow: visible !important;
184
+ text-overflow: clip !important;
185
+ line-height: normal !important;
186
+ word-break: break-all !important;
187
+ font-size: 10px;
188
+ font-weight: normal;
189
+ }
190
+ .uni-collapse-item-error {
191
+ .uni-collapse-item__title-text {
192
+ color: red !important;
193
+ }
194
+ }
195
+ }
196
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <uni-popup ref="popupRef" background-color="#fff">
2
+ <uni-popup class="oa-debug-popup" ref="popupRef" background-color="none">
3
3
  <view style="height: 500px; background-color: white; width: 100vw">
4
4
  <scroll-view scroll-x class="tab-scroll" :show-scrollbar="false">
5
5
  <view class="tab-container">
@@ -34,6 +34,9 @@
34
34
  <System />
35
35
  </template>
36
36
  <template v-if="current === 6">
37
+ <Audio />
38
+ </template>
39
+ <template v-if="current === 7">
37
40
  <DevTools />
38
41
  </template>
39
42
  </view>
@@ -61,10 +64,11 @@
61
64
  import Storage from './storage.vue';
62
65
  import Console from './console.vue';
63
66
  import System from './system.vue';
67
+ import Audio from './audio.vue';
64
68
  import DevTools from './dev-tools.vue';
65
69
 
66
70
  const popupRef = ref<any>();
67
- const list = ref(['console', 'network', 'event', 'error', 'storage', 'system', 'dev-tools']);
71
+ const list = ref(['console', 'network', 'event', 'error', 'storage', 'system', 'audio', 'dev-tools']);
68
72
  const current = ref(0);
69
73
 
70
74
  const handleTabClick = (index: number) => {
@@ -98,11 +102,14 @@
98
102
  </script>
99
103
 
100
104
  <style lang="scss" scoped>
105
+ .oa-debug-popup {
106
+ z-index: 10000 !important;
107
+ }
101
108
  .debug-button {
102
109
  width: 40px;
103
110
  height: 40px;
104
111
  position: fixed;
105
- z-index: 1000;
112
+ z-index: 10000;
106
113
  border-radius: 50%;
107
114
  display: flex;
108
115
  justify-content: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uni-oaview",
3
- "version": "1.3.00",
3
+ "version": "1.4.00",
4
4
  "description": "uniapp小程序组件库",
5
5
  "main": "dist/index.esm.js",
6
6
  "typings": "dist/index.d.ts",