npmapps 1.0.21 → 1.0.23

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 (105) hide show
  1. package/app/Wscats.vue-1.0.26.vsix +0 -0
  2. package/app/febean.vue-format-0.1.8.vsix +0 -0
  3. package/app/wujie-vue3-child/.claude/settings.local.json +8 -0
  4. package/app/wujie-vue3-child/.vscode/extensions.json +3 -0
  5. package/app/wujie-vue3-child/PROJECT_MEMORY.md +427 -0
  6. package/app/wujie-vue3-child/README.md +5 -0
  7. package/app/wujie-vue3-child/index.html +13 -0
  8. package/app/wujie-vue3-child/package-lock.json +5744 -0
  9. package/app/wujie-vue3-child/package.json +28 -0
  10. package/app/wujie-vue3-child/public/vite.svg +1 -0
  11. package/app/wujie-vue3-child/src/App.vue +130 -0
  12. package/app/wujie-vue3-child/src/assets/vue.svg +1 -0
  13. package/app/wujie-vue3-child/src/components/HelloWorld.vue +43 -0
  14. package/app/wujie-vue3-child/src/components/tags-view.vue +193 -0
  15. package/app/wujie-vue3-child/src/components/tags-view1.vue +131 -0
  16. package/app/wujie-vue3-child/src/hooks/useClickOutside.js +11 -0
  17. package/app/wujie-vue3-child/src/hooks/useTableDragSort.js +28 -0
  18. package/app/wujie-vue3-child/src/main.js +15 -0
  19. package/app/wujie-vue3-child/src/router/index.js +104 -0
  20. package/app/wujie-vue3-child/src/store/tagsViewStroe.js +34 -0
  21. package/app/wujie-vue3-child/src/style.css +4 -0
  22. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/README.md +836 -0
  23. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/REFLEX_EXAMPLES.md +728 -0
  24. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.jsx +687 -0
  25. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentPersonnelSelector.module.scss +560 -0
  26. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.jsx +570 -0
  27. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelector.module.scss +330 -0
  28. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.jsx +378 -0
  29. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/DepartmentSelectorV2.module.scss +228 -0
  30. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.jsx +399 -0
  31. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/OptionsSelector.module.scss +252 -0
  32. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.jsx +585 -0
  33. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PersonnelSelector.module.scss +331 -0
  34. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.jsx +392 -0
  35. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/PopoverSelector.module.scss +39 -0
  36. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/README.md +248 -0
  37. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/components/SelectorTrigger.jsx +194 -0
  38. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/index.jsx +1459 -0
  39. package/app/wujie-vue3-child/src/views/aiCoach/departmentPersonnel/mockData.js +301 -0
  40. package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.jsx +28 -4
  41. package/app/wujie-vue3-child/src/views/aiCoach/index.jsx +32 -0
  42. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.jsx +121 -0
  43. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ChartsPanel/index.module.scss +76 -0
  44. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/DonutChart/index.jsx +104 -0
  45. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.jsx +75 -0
  46. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/PracticeTable/index.module.scss +12 -0
  47. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.jsx +62 -0
  48. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankBarChart/index.module.scss +43 -0
  49. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.jsx +29 -0
  50. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingGroup/index.module.scss +5 -0
  51. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.jsx +58 -0
  52. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/RankingList/index.module.scss +85 -0
  53. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.jsx +92 -0
  54. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/ScriptStatsPanel/index.module.scss +56 -0
  55. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.jsx +40 -0
  56. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/StatCardsRow/index.module.scss +53 -0
  57. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsDonut.jsx +106 -0
  58. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/components/echarts/EchartsRankBar.jsx +132 -0
  59. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.jsx +176 -0
  60. package/app/wujie-vue3-child/src/views/aiCoach/practiceStatus/index.module.scss +96 -0
  61. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.jsx +162 -0
  62. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/CoachReport/index.module.scss +16 -0
  63. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.jsx +29 -0
  64. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ComprehensiveEvaluation/index.module.scss +25 -0
  65. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.jsx +106 -0
  66. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueBubble/index.module.scss +164 -0
  67. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.jsx +182 -0
  68. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DialogueRecord/index.module.scss +203 -0
  69. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.jsx +145 -0
  70. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionDetail/index.module.scss +126 -0
  71. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.jsx +67 -0
  72. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/DimensionScores/index.module.scss +105 -0
  73. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.jsx +81 -0
  74. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ReportHeader/index.module.scss +47 -0
  75. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.jsx +64 -0
  76. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/RoleInfo/index.module.scss +85 -0
  77. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.jsx +39 -0
  78. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/ScoreBadge/index.module.scss +44 -0
  79. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.jsx +83 -0
  80. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/components/SubDimensionItem/index.module.scss +101 -0
  81. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.jsx +50 -0
  82. package/app/wujie-vue3-child/src/views/aiCoach/reportDetail/index.module.scss +25 -0
  83. package/app/wujie-vue3-child/src/views/child-to-parent.vue +117 -0
  84. package/app/wujie-vue3-child/src/views/home.vue +53 -0
  85. package/app/wujie-vue3-child/src/views/jsx/btnSelect/btnSelect.vue +169 -0
  86. package/app/wujie-vue3-child/src/views/jsx/btnSelect/index.vue +69 -0
  87. package/app/wujie-vue3-child/src/views/jsx/com.vue +44 -0
  88. package/app/wujie-vue3-child/src/views/jsx/dialog.jsx +66 -0
  89. package/app/wujie-vue3-child/src/views/jsx/index.vue +72 -0
  90. package/app/wujie-vue3-child/src/views/jsx/props.vue +33 -0
  91. package/app/wujie-vue3-child/src/views/parent-to-child.vue +225 -0
  92. package/app/wujie-vue3-child/src/views/phone-code.vue +318 -0
  93. package/app/wujie-vue3-child/src/views/router-jump.vue +123 -0
  94. package/app/wujie-vue3-child/src/views/test.vue +192 -0
  95. package/app/wujie-vue3-child/vite.config.js +15 -0
  96. package/package.json +1 -1
  97. package/app/aiCoach/index.jsx +0 -20
  98. package/npmapps-1.0.20.tgz +0 -0
  99. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.jsx +0 -0
  100. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/collapseExpand/index.module.scss +0 -0
  101. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/dialogueSegment/index.module.scss +0 -0
  102. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.jsx +0 -0
  103. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/index.module.scss +0 -0
  104. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.jsx +0 -0
  105. /package/app/{aiCoach → wujie-vue3-child/src/views/aiCoach}/scriptTable/inputColumn/index.module.scss +0 -0
@@ -0,0 +1,72 @@
1
+ <script lang="jsx">
2
+ import { defineComponent, ref, h, Fragment, getCurrentInstance } from "vue";
3
+ import PropsView from "./props.vue";
4
+ import openDialog from "./dialog.jsx";
5
+ import ComView from "./com.vue";
6
+ import BtnSelect from "./btnSelect/index.vue";
7
+ export default defineComponent({
8
+ name: "JsxView",
9
+ setup() {
10
+ const count = ref(0);
11
+ const propsViewRef = ref(null);
12
+ const countAdd = () => {
13
+ propsViewRef.value.countAdd();
14
+ };
15
+ const comCount = ref(0);
16
+ const open = () => {
17
+ const { appContext } = getCurrentInstance() || {};
18
+ let dialog = {};
19
+ const options = {
20
+ props: {
21
+ title: "hello dialog",
22
+ },
23
+ events: {
24
+ onClose: () => {
25
+ console.log("close11");
26
+ },
27
+ },
28
+ slots: {
29
+ default: () => <ComView count={comCount.value} dialog={dialog} />,
30
+ title: () => <div>title slot</div>,
31
+ footer: () => <div>footer slot</div>,
32
+ },
33
+ };
34
+ dialog.close = openDialog(options, appContext).close;
35
+ };
36
+ const activeTab = ref("btnSelect");
37
+ return () => (
38
+ <>
39
+ <el-tabs v-model={activeTab.value} type="border-card">
40
+ <el-tab-pane label="首页" name="first"> <div>
41
+ 123
42
+ <span>
43
+ <el-button type="primary" onClick={open}>
44
+ open dialog
45
+ </el-button>
46
+ <el-button type="primary" onClick={countAdd}>
47
+ props countAdd
48
+ </el-button>
49
+ <div>count: {count.value}</div>
50
+ <PropsView
51
+ ref={propsViewRef}
52
+ msg="hello props"
53
+ onMyEvent={() => {
54
+ count.value++;
55
+ }}
56
+ >
57
+ {{
58
+ default: () => <div>default slot</div>,
59
+ }}
60
+ </PropsView>
61
+ </span>
62
+ </div></el-tab-pane>
63
+ <el-tab-pane label="按钮下拉框" name="btnSelect">
64
+ <BtnSelect />
65
+ </el-tab-pane>
66
+ </el-tabs>
67
+
68
+ </>
69
+ );
70
+ },
71
+ });
72
+ </script>
@@ -0,0 +1,33 @@
1
+ <script lang="jsx">
2
+ import { defineComponent, ref, h, Fragment } from 'vue'
3
+
4
+ export default defineComponent({
5
+ name: 'PropsView',
6
+ emits: ['myEvent'],
7
+ setup(props, { attrs, emit ,slots ,expose }) {
8
+ console.log(props, 'props');
9
+ console.log(attrs, 'attrs');
10
+ console.log(emit, 'emit');
11
+ console.log(slots, 'slots');
12
+ console.log(expose, 'expose');
13
+ const count = ref(0);
14
+ const countAdd = () => {
15
+ count.value++;
16
+ }
17
+ expose({
18
+ countAdd,
19
+ })
20
+ return () => <>
21
+ <div>
22
+ {attrs.msg}
23
+ <div>props count: {count.value}</div>
24
+ {slots.default()}
25
+ <el-button type="primary" onClick={() => {
26
+ console.log('myEvent');
27
+
28
+ emit('myEvent')
29
+ }}>countAdd</el-button>
30
+ </div></>
31
+ }
32
+ })
33
+ </script>
@@ -0,0 +1,225 @@
1
+ <template>
2
+ <div class="parent-to-child">
3
+ <h2 class="page-title">消息接收中心</h2>
4
+
5
+ <div class="message-container">
6
+ <div class="message-section">
7
+ <div class="section-header">
8
+ <h3>全局广播消息</h3>
9
+ <el-button type="primary" size="small" @click="clearGlobalMessages">
10
+ 清空消息
11
+ </el-button>
12
+ </div>
13
+ <div class="message-list" v-if="globalMessages.length">
14
+ <div v-for="(msg, index) in globalMessages"
15
+ :key="index"
16
+ class="message-item">
17
+ <div class="message-header">
18
+ <span class="message-time">{{ msg.time }}</span>
19
+ <span class="message-type" :class="msg.type">{{ msg.type }}</span>
20
+ </div>
21
+ <h4 class="message-title">{{ msg.title }}</h4>
22
+ <p class="message-content">{{ msg.message }}</p>
23
+ </div>
24
+ </div>
25
+ <div v-else class="empty-message">
26
+ 暂无消息
27
+ </div>
28
+ </div>
29
+
30
+ <div class="message-section">
31
+ <div class="section-header">
32
+ <h3>定向消息</h3>
33
+ <el-button type="primary" size="small" @click="clearDirectMessages">
34
+ 清空消息
35
+ </el-button>
36
+ </div>
37
+ <div class="message-list" v-if="directMessages.length">
38
+ <div v-for="(msg, index) in directMessages"
39
+ :key="index"
40
+ class="message-item">
41
+ <div class="message-header">
42
+ <span class="message-time">{{ msg.time }}</span>
43
+ <span class="message-type" :class="msg.type">{{ msg.type }}</span>
44
+ </div>
45
+ <h4 class="message-title">{{ msg.title }}</h4>
46
+ <p class="message-content">{{ msg.message }}</p>
47
+ </div>
48
+ </div>
49
+ <div v-else class="empty-message">
50
+ 暂无消息
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <script setup>
58
+ import { ref, onMounted } from 'vue'
59
+
60
+ const globalMessages = ref([])
61
+ const directMessages = ref([])
62
+
63
+ const formatTime = () => {
64
+ const now = new Date()
65
+ return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`
66
+ }
67
+
68
+ const clearGlobalMessages = () => {
69
+ globalMessages.value = []
70
+ }
71
+
72
+ const clearDirectMessages = () => {
73
+ directMessages.value = []
74
+ }
75
+
76
+ onMounted(() => {
77
+ // 监听全局广播消息
78
+ window.$wujie?.bus.$on('global-message', (data) => {
79
+ globalMessages.value.unshift({
80
+ ...data,
81
+ time: formatTime()
82
+ })
83
+ })
84
+
85
+ // 监听定向消息
86
+ window.$wujie?.bus.$on('vue3-child-message', (data) => {
87
+ directMessages.value.unshift({
88
+ ...data,
89
+ time: formatTime()
90
+ })
91
+ })
92
+ })
93
+ </script>
94
+
95
+ <style scoped>
96
+ .parent-to-child {
97
+ padding: 24px;
98
+ background-color: #f5f7fa;
99
+ min-height: 100vh;
100
+ }
101
+
102
+ .page-title {
103
+ color: #303133;
104
+ margin-bottom: 24px;
105
+ font-size: 24px;
106
+ }
107
+
108
+ .message-container {
109
+ display: grid;
110
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
111
+ gap: 24px;
112
+ }
113
+
114
+ .message-section {
115
+ background: white;
116
+ border-radius: 8px;
117
+ padding: 20px;
118
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
119
+ }
120
+
121
+ .section-header {
122
+ display: flex;
123
+ justify-content: space-between;
124
+ align-items: center;
125
+ margin-bottom: 16px;
126
+ padding-bottom: 16px;
127
+ border-bottom: 1px solid #ebeef5;
128
+ }
129
+
130
+ .section-header h3 {
131
+ margin: 0;
132
+ color: #303133;
133
+ font-size: 18px;
134
+ }
135
+
136
+ .message-list {
137
+ max-height: 500px;
138
+ overflow-y: auto;
139
+ }
140
+
141
+ .message-item {
142
+ padding: 12px;
143
+ border-bottom: 1px solid #ebeef5;
144
+ transition: background-color 0.3s;
145
+ }
146
+
147
+ .message-item:hover {
148
+ background-color: #f5f7fa;
149
+ }
150
+
151
+ .message-time {
152
+ font-size: 12px;
153
+ color: #909399;
154
+ }
155
+
156
+ .message-content {
157
+ margin: 8px 0 0;
158
+ color: #606266;
159
+ line-height: 1.5;
160
+ }
161
+
162
+ .empty-message {
163
+ text-align: center;
164
+ color: #909399;
165
+ padding: 30px 0;
166
+ }
167
+
168
+ /* 滚动条样式 */
169
+ .message-list::-webkit-scrollbar {
170
+ width: 6px;
171
+ }
172
+
173
+ .message-list::-webkit-scrollbar-thumb {
174
+ background: #c0c4cc;
175
+ border-radius: 3px;
176
+ }
177
+
178
+ .message-list::-webkit-scrollbar-track {
179
+ background: #f5f7fa;
180
+ }
181
+
182
+ .message-header {
183
+ display: flex;
184
+ justify-content: space-between;
185
+ align-items: center;
186
+ }
187
+
188
+ .message-type {
189
+ padding: 2px 6px;
190
+ border-radius: 4px;
191
+ font-size: 12px;
192
+ }
193
+
194
+ .message-type.info {
195
+ background-color: #ecf5ff;
196
+ color: #409eff;
197
+ }
198
+
199
+ .message-type.success {
200
+ background-color: #f0f9eb;
201
+ color: #67c23a;
202
+ }
203
+
204
+ .message-type.warning {
205
+ background-color: #fdf6ec;
206
+ color: #e6a23c;
207
+ }
208
+
209
+ .message-type.error {
210
+ background-color: #fef0f0;
211
+ color: #f56c6c;
212
+ }
213
+
214
+ .message-title {
215
+ margin: 8px 0;
216
+ font-size: 14px;
217
+ color: #303133;
218
+ }
219
+
220
+ .message-content {
221
+ margin: 8px 0 0;
222
+ color: #606266;
223
+ line-height: 1.5;
224
+ }
225
+ </style>
@@ -0,0 +1,318 @@
1
+ <template>
2
+ <div>
3
+ <button class="open-dialog-btn" @click="showDialog = true">获取验证码</button>
4
+
5
+ <el-dialog
6
+ v-model="showDialog"
7
+ title="验证码"
8
+ width="400px"
9
+ :show-close="true"
10
+ :close-on-click-modal="false"
11
+ @opened="handleDialogOpened"
12
+ >
13
+ <div class="code-container">
14
+ <div class="code-title">输入短信验证码</div>
15
+ <div class="code-tip">短信验证码发送至 182 **** 1234</div>
16
+
17
+ <div class="code-input-box">
18
+ <el-input
19
+ v-for="(item, index) in 6"
20
+ :key="index"
21
+ v-model="codeArray[index]"
22
+ maxlength="1"
23
+ :input-style="{ textAlign: 'center' }"
24
+ @input="(value) => handleInput(value, index)"
25
+ @keyup.delete="handleDelete(index)"
26
+ ref="inputRefs"
27
+ />
28
+ </div>
29
+
30
+ <div class="resend" @click="resendCode">
31
+ {{ counting ? `${counter}s后重新获取` : '重新获取' }}
32
+ </div>
33
+
34
+ <el-button
35
+ type="primary"
36
+ :loading="loading"
37
+ @click="handleSubmit"
38
+ >
39
+ 确认
40
+ </el-button>
41
+ </div>
42
+ </el-dialog>
43
+
44
+ <div v-if="submittedCode" class="submitted-code">
45
+ 您输入的验证码是: {{ submittedCode }}
46
+ </div>
47
+
48
+ <el-dialog
49
+ v-model="dialogVisible"
50
+ title="提示"
51
+ width="30%"
52
+ :before-close="handleClose"
53
+ @opened="handleDialogOpened"
54
+ >
55
+ <span>{{ dialogMessage }}</span>
56
+ <template #footer>
57
+ <span class="dialog-footer">
58
+ <el-button ref="cancelBtn" @click="dialogVisible = false">取消</el-button>
59
+ <el-button type="primary" ref="confirmBtn" @click="confirmDialog">
60
+ 确定
61
+ </el-button>
62
+ </span>
63
+ </template>
64
+ </el-dialog>
65
+ </div>
66
+ </template>
67
+
68
+ <script setup>
69
+ import { ref, onUnmounted, nextTick } from 'vue'
70
+ import { ElMessage } from 'element-plus'
71
+
72
+ const showDialog = ref(false)
73
+ const codeArray = ref(['', '', '', '', '', ''])
74
+ const inputRefs = ref([])
75
+ const counter = ref(60)
76
+ const counting = ref(false)
77
+ let timer = null
78
+
79
+ const handleInput = (value, index) => {
80
+ // 确保输入为数字
81
+ if (!/^\d*$/.test(value)) {
82
+ codeArray.value[index] = ''
83
+ return
84
+ }
85
+
86
+ // 更新值
87
+ codeArray.value[index] = value.slice(0, 1)
88
+
89
+ // 自动跳转到下一个输入框
90
+ if (value && index < 5) {
91
+ inputRefs.value[index + 1]?.focus()
92
+ }
93
+ }
94
+
95
+ const handleDelete = (index) => {
96
+ if (codeArray.value[index] === '' && index > 0) {
97
+ inputRefs.value[index - 1]?.focus()
98
+ }
99
+ }
100
+
101
+ // 重新发送验证码
102
+ const resendCode = () => {
103
+ if (counting.value) return
104
+ counting.value = true
105
+ counter.value = 60
106
+ timer = setInterval(() => {
107
+ if (counter.value > 0) {
108
+ counter.value--
109
+ } else {
110
+ counting.value = false
111
+ clearInterval(timer)
112
+ }
113
+ }, 1000)
114
+ }
115
+
116
+ // 替换原来的 alert 为 ElMessage
117
+ const showMessage = (message, type = 'warning') => {
118
+ ElMessage({
119
+ message,
120
+ type,
121
+ })
122
+ }
123
+
124
+ // 弹窗相关状态
125
+ const dialogVisible = ref(false)
126
+ const dialogMessage = ref('')
127
+ const submittedCode = ref('') // 用于存储提交的验证码
128
+ const confirmBtn = ref(null)
129
+
130
+ const handleClose = () => {
131
+ dialogVisible.value = false
132
+ }
133
+
134
+ // 处理弹窗打开时自动聚焦确认按钮
135
+ const handleDialogOpened = () => {
136
+ nextTick(() => {
137
+ if (inputRefs.value && inputRefs.value[0]) {
138
+ inputRefs.value[0].focus()
139
+ }
140
+ })
141
+ }
142
+
143
+ const confirmDialog = () => {
144
+ dialogVisible.value = false
145
+ // 保存验证码到显示区域
146
+ submittedCode.value = codeArray.value.join('')
147
+ }
148
+
149
+ // 确认提交
150
+ const handleSubmit = async () => {
151
+ if (codeArray.value.some(code => !code)) {
152
+ ElMessage.warning('验证码不能为空')
153
+ return
154
+ }
155
+ try {
156
+ // 这里是你的验证逻辑
157
+ // await verifyCode()
158
+
159
+ // 保存并显示验证码
160
+ submittedCode.value = codeArray.value.join('')
161
+ // 关闭弹窗
162
+ showDialog.value = false
163
+ ElMessage.success('验证成功')
164
+ } catch (error) {
165
+ ElMessage.error('验证失败')
166
+ } finally {
167
+ }
168
+ }
169
+
170
+ // 组件销毁时清除定时器
171
+ onUnmounted(() => {
172
+ if (timer) {
173
+ clearInterval(timer)
174
+ }
175
+ })
176
+ </script>
177
+
178
+ <style scoped>
179
+ .phone-code-dialog {
180
+ position: fixed;
181
+ top: 0;
182
+ left: 0;
183
+ width: 100%;
184
+ height: 100%;
185
+ z-index: 999;
186
+ }
187
+
188
+ .dialog-mask {
189
+ position: absolute;
190
+ top: 0;
191
+ left: 0;
192
+ width: 100%;
193
+ height: 100%;
194
+ background: rgba(0, 0, 0, 0.5);
195
+ }
196
+
197
+ .dialog-content {
198
+ position: absolute;
199
+ left: 50%;
200
+ top: 50%;
201
+ transform: translate(-50%, -50%);
202
+ width: 90%;
203
+ max-width: 320px;
204
+ background: #fff;
205
+ border-radius: 12px;
206
+ overflow: hidden;
207
+ }
208
+
209
+ .close-icon {
210
+ position: absolute;
211
+ right: 10px;
212
+ top: 10px;
213
+ font-size: 24px;
214
+ color: #999;
215
+ cursor: pointer;
216
+ z-index: 1;
217
+ }
218
+
219
+ .code-container {
220
+ width: 100%;
221
+ padding: 20px;
222
+ box-sizing: border-box;
223
+ }
224
+
225
+ .code-title {
226
+ font-size: 18px;
227
+ font-weight: bold;
228
+ margin-bottom: 8px;
229
+ }
230
+
231
+ .code-tip {
232
+ color: #666;
233
+ font-size: 14px;
234
+ margin-bottom: 20px;
235
+ }
236
+
237
+ .code-input-box {
238
+ display: flex;
239
+ justify-content: space-between;
240
+ margin-bottom: 20px;
241
+ gap: 8px;
242
+ }
243
+
244
+ .code-input-box input {
245
+ width: 40px;
246
+ height: 40px;
247
+ border: 1.5px solid #ddd;
248
+ border-radius: 8px;
249
+ text-align: center;
250
+ font-size: 18px;
251
+ transition: all 0.3s;
252
+ background-color: #f8f9fa;
253
+ }
254
+
255
+ .code-input-box input:focus {
256
+ border-color: #ff4d4f;
257
+ outline: none;
258
+ box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
259
+ background-color: #fff;
260
+ }
261
+
262
+ /* 修改input类型为tel,但仍然保留number的样式控制 */
263
+ .code-input-box input[type="tel"] {
264
+ -moz-appearance: textfield;
265
+ }
266
+
267
+ .code-input-box input::-webkit-outer-spin-button,
268
+ .code-input-box input::-webkit-inner-spin-button {
269
+ -webkit-appearance: none;
270
+ margin: 0;
271
+ }
272
+
273
+ .resend {
274
+ text-align: right;
275
+ color: #1890ff;
276
+ font-size: 14px;
277
+ cursor: pointer;
278
+ margin-bottom: 20px;
279
+ }
280
+
281
+ .confirm-btn {
282
+ width: 100%;
283
+ height: 44px;
284
+ background: #ff4d4f;
285
+ color: #fff;
286
+ border: none;
287
+ border-radius: 22px;
288
+ font-size: 16px;
289
+ cursor: pointer;
290
+ }
291
+
292
+ .confirm-btn:active {
293
+ opacity: 0.8;
294
+ }
295
+
296
+ .open-dialog-btn {
297
+ padding: 8px 20px;
298
+ background: #ff4d4f;
299
+ color: #fff;
300
+ border: none;
301
+ border-radius: 4px;
302
+ font-size: 14px;
303
+ cursor: pointer;
304
+ }
305
+
306
+ .open-dialog-btn:active {
307
+ opacity: 0.8;
308
+ }
309
+
310
+ .submitted-code {
311
+ margin-top: 20px;
312
+ padding: 10px;
313
+ background-color: #f0f9eb;
314
+ border-radius: 4px;
315
+ color: #67c23a;
316
+ font-size: 14px;
317
+ }
318
+ </style>