Commit 69f84b7e2188af7623934e1e458a5a375ac236c8

Authored by tianwu
1 parent f2911672

fix(view):兼容性优化

apps/web-payment/package.json
@@ -46,6 +46,7 @@ @@ -46,6 +46,7 @@
46 "element-plus": "catalog:", 46 "element-plus": "catalog:",
47 "pinia": "catalog:", 47 "pinia": "catalog:",
48 "qs": "catalog:", 48 "qs": "catalog:",
  49 + "vconsole": "^3.15.1",
49 "vue": "catalog:", 50 "vue": "catalog:",
50 "vue-router": "catalog:" 51 "vue-router": "catalog:"
51 }, 52 },
apps/web-payment/src/views/payment/component/PasswordInput.vue
@@ -127,15 +127,14 @@ const handlePaste = (index: number, event: ClipboardEvent) => { @@ -127,15 +127,14 @@ const handlePaste = (index: number, event: ClipboardEvent) => {
127 } 127 }
128 }; 128 };
129 129
130 -// 处理点击输入框 - 禁止点击跳转  
131 -const handleFocus = (index: number, event: FocusEvent) => {  
132 - event.preventDefault(); 130 +// 处理聚焦事件 - 定位到正确输入位置并唤起软键盘
  131 +const handleFocus = (index: number) => {
133 // 找到第一个空的输入框位置 132 // 找到第一个空的输入框位置
134 const firstEmptyIndex = passwordValues.value.findIndex((v) => !v); 133 const firstEmptyIndex = passwordValues.value.findIndex((v) => !v);
135 const targetIndex = 134 const targetIndex =
136 firstEmptyIndex === -1 ? props.length - 1 : firstEmptyIndex; 135 firstEmptyIndex === -1 ? props.length - 1 : firstEmptyIndex;
137 136
138 - // 如果点击的不是当前应该输入的位置,则重新聚焦到正确位置 137 + // 如果聚焦的不是当前应该输入的位置,则重新聚焦到正确位置
139 if (index !== targetIndex) { 138 if (index !== targetIndex) {
140 nextTick(() => { 139 nextTick(() => {
141 inputRefs.value[targetIndex]?.focus(); 140 inputRefs.value[targetIndex]?.focus();
@@ -144,6 +143,18 @@ const handleFocus = (index: number, event: FocusEvent) => { @@ -144,6 +143,18 @@ const handleFocus = (index: number, event: FocusEvent) => {
144 currentIndex.value = targetIndex; 143 currentIndex.value = targetIndex;
145 }; 144 };
146 145
  146 +// 处理点击事件 - 确保软键盘唤起
  147 +const handleClick = (index: number) => {
  148 + // 在下一帧确保输入框获得焦点,从而唤起软键盘
  149 + nextTick(() => {
  150 + const firstEmptyIndex = passwordValues.value.findIndex((v) => !v);
  151 + const targetIndex =
  152 + firstEmptyIndex === -1 ? props.length - 1 : firstEmptyIndex;
  153 + inputRefs.value[targetIndex]?.focus();
  154 + currentIndex.value = targetIndex;
  155 + });
  156 +};
  157 +
147 // 检查是否完成输入 158 // 检查是否完成输入
148 const checkComplete = () => { 159 const checkComplete = () => {
149 const password = passwordValues.value.join(''); 160 const password = passwordValues.value.join('');
@@ -246,8 +257,8 @@ defineExpose({ @@ -246,8 +257,8 @@ defineExpose({
246 @input="handleInput(index, $event)" 257 @input="handleInput(index, $event)"
247 @keydown="handleKeydown(index, $event)" 258 @keydown="handleKeydown(index, $event)"
248 @paste="handlePaste(index, $event)" 259 @paste="handlePaste(index, $event)"
249 - @focus="handleFocus(index, $event)"  
250 - @mousedown.prevent 260 + @focus="handleFocus(index)"
  261 + @click="handleClick(index)"
251 /> 262 />
252 </div> 263 </div>
253 264
apps/web-payment/src/views/payment/index.vue
@@ -13,6 +13,7 @@ import { @@ -13,6 +13,7 @@ import {
13 } from '@element-plus/icons-vue'; 13 } from '@element-plus/icons-vue';
14 import { ElButton, ElDialog, ElIcon, ElMessage, ElRadio } from 'element-plus'; 14 import { ElButton, ElDialog, ElIcon, ElMessage, ElRadio } from 'element-plus';
15 import qs from 'qs'; 15 import qs from 'qs';
  16 +import VConsole from 'vconsole';
16 17
17 import { 18 import {
18 getOpenId, 19 getOpenId,
@@ -73,6 +74,24 @@ const paymentSuccess = ref&lt;boolean&gt;(false); @@ -73,6 +74,24 @@ const paymentSuccess = ref&lt;boolean&gt;(false);
73 const payErrorDialog = ref<boolean>(false); 74 const payErrorDialog = ref<boolean>(false);
74 const errorMessage = ref<string>('支付失败'); 75 const errorMessage = ref<string>('支付失败');
75 76
  77 +const handleShowConsole = () => {
  78 + const vConsole = new VConsole({ theme: 'dark' });
  79 +};
  80 +
  81 +let pressTimer = null;
  82 +
  83 +const onPressStart = () => {
  84 + pressTimer = setTimeout(() => {
  85 + // console.log('已长按 6 秒');
  86 + handleShowConsole();
  87 + }, 6000);
  88 +};
  89 +
  90 +const onPressEnd = () => {
  91 + clearTimeout(pressTimer);
  92 + pressTimer = null;
  93 +};
  94 +
76 // 计算显示金额 95 // 计算显示金额
77 const displayAmount = computed(() => { 96 const displayAmount = computed(() => {
78 return fenToYuan(orderInfoData.value?.amount || 0); 97 return fenToYuan(orderInfoData.value?.amount || 0);
@@ -177,9 +196,9 @@ const handlepayBtnShowClick = async (pipeline: Pipeline) =&gt; { @@ -177,9 +196,9 @@ const handlepayBtnShowClick = async (pipeline: Pipeline) =&gt; {
177 196
178 // 判断是否是园区卡支付 197 // 判断是否是园区卡支付
179 if (channelName.includes('园区卡') || channelName.includes('卡支付')) { 198 if (channelName.includes('园区卡') || channelName.includes('卡支付')) {
  199 + showCardDialog.value = true;
180 // 如果还没有加载园区卡列表,先加载 200 // 如果还没有加载园区卡列表,先加载
181 if (cardList.value.length === 0) { 201 if (cardList.value.length === 0) {
182 - showCardDialog.value = true;  
183 await getListUserCards(); 202 await getListUserCards();
184 } 203 }
185 } else { 204 } else {
@@ -260,8 +279,8 @@ const queryPayment = async () =&gt; { @@ -260,8 +279,8 @@ const queryPayment = async () =&gt; {
260 payee: orderInfoData.value.mchName, 279 payee: orderInfoData.value.mchName,
261 }; 280 };
262 const queryString = qs.stringify(params); 281 const queryString = qs.stringify(params);
263 - if (typeof jWeixin !== 'undefined' && jWeixin.miniProgram) {  
264 - jWeixin.miniProgram.redirectTo({ 282 + if (typeof wx !== 'undefined' && wx.miniProgram) {
  283 + wx.miniProgram.redirectTo({
265 url: `/packageA/pages/wxPay/index?${queryString}`, 284 url: `/packageA/pages/wxPay/index?${queryString}`,
266 }); 285 });
267 loading.value = false; 286 loading.value = false;
@@ -287,8 +306,8 @@ const queryPayment = async () =&gt; { @@ -287,8 +306,8 @@ const queryPayment = async () =&gt; {
287 const queryString = qs.stringify(pramsData); 306 const queryString = qs.stringify(pramsData);
288 307
289 // 跳转到微信支付页面 308 // 跳转到微信支付页面
290 - if (typeof jWeixin !== 'undefined' && jWeixin.miniProgram) {  
291 - jWeixin.miniProgram.navigateTo({ 309 + if (typeof wx !== 'undefined' && wx.miniProgram) {
  310 + wx.miniProgram.navigateTo({
292 url: `/packageA/pages/wxPay/index?${queryString}`, 311 url: `/packageA/pages/wxPay/index?${queryString}`,
293 }); 312 });
294 loading.value = false; 313 loading.value = false;
@@ -331,6 +350,15 @@ const handlePay = async () =&gt; { @@ -331,6 +350,15 @@ const handlePay = async () =&gt; {
331 // 园区卡支付逻辑 350 // 园区卡支付逻辑
332 try { 351 try {
333 showPasswordDialog.value = true; 352 showPasswordDialog.value = true;
  353 + const scrollHeight = Math.max(
  354 + document.body.scrollHeight,
  355 + document.documentElement.scrollHeight,
  356 + );
  357 +
  358 + window.scrollTo({
  359 + top: scrollHeight,
  360 + behavior: 'smooth',
  361 + });
334 } catch {} 362 } catch {}
335 } else { 363 } else {
336 // 其他支付方式(微信、支付宝等) 364 // 其他支付方式(微信、支付宝等)
@@ -418,10 +446,15 @@ const paySuccessHandler = (data: any) =&gt; { @@ -418,10 +446,15 @@ const paySuccessHandler = (data: any) =&gt; {
418 }); 446 });
419 }; 447 };
420 448
421 -const payFailHandler = (msg: any) => {}; 449 +const payFailHandler = (msg: any) => {
  450 + errorMessage.value = msg || '获取订单信息失败';
  451 + payErrorDialog.value = true;
  452 +};
422 453
423 const payTimeoutHandler = () => { 454 const payTimeoutHandler = () => {
424 // errorMessage: '支付结果查询超时,请稍后在订单中查看支付状态' 455 // errorMessage: '支付结果查询超时,请稍后在订单中查看支付状态'
  456 + errorMessage.value = '支付结果查询超时,请稍后在订单中查看支付状态';
  457 + payErrorDialog.value = true;
425 }; 458 };
426 459
427 const checkPayResult = async (paymentId: number | string) => { 460 const checkPayResult = async (paymentId: number | string) => {
@@ -492,7 +525,15 @@ init(); @@ -492,7 +525,15 @@ init();
492 </script> 525 </script>
493 526
494 <template> 527 <template>
495 - <div class="cashier-container" v-loading="loadLoading"> 528 + <div
  529 + class="cashier-container"
  530 + v-loading="loadLoading"
  531 + @mousedown="onPressStart()"
  532 + @mouseup="onPressEnd()"
  533 + @mouseleave="onPressEnd()"
  534 + @touchstart="onPressStart()"
  535 + @touchend="onPressEnd()"
  536 + >
496 <!-- 无效参数提示 --> 537 <!-- 无效参数提示 -->
497 <div v-if="!hasValidParams" class="error-container"> 538 <div v-if="!hasValidParams" class="error-container">
498 <div class="error-content"> 539 <div class="error-content">
pnpm-lock.yaml
@@ -883,6 +883,9 @@ importers: @@ -883,6 +883,9 @@ importers:
883 qs: 883 qs:
884 specifier: 'catalog:' 884 specifier: 'catalog:'
885 version: 6.14.0 885 version: 6.14.0
  886 + vconsole:
  887 + specifier: ^3.15.1
  888 + version: 3.15.1
886 vue: 889 vue:
887 specifier: ^3.5.24 890 specifier: ^3.5.24
888 version: 3.5.24(typescript@5.9.3) 891 version: 3.5.24(typescript@5.9.3)
@@ -5742,6 +5745,10 @@ packages: @@ -5742,6 +5745,10 @@ packages:
5742 resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} 5745 resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
5743 engines: {node: '>=18'} 5746 engines: {node: '>=18'}
5744 5747
  5748 + copy-text-to-clipboard@3.2.2:
  5749 + resolution: {integrity: sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==}
  5750 + engines: {node: '>=12'}
  5751 +
5745 core-js-compat@3.46.0: 5752 core-js-compat@3.46.0:
5746 resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} 5753 resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==}
5747 5754
@@ -8035,6 +8042,9 @@ packages: @@ -8035,6 +8042,9 @@ packages:
8035 resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} 8042 resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==}
8036 engines: {node: '>=10'} 8043 engines: {node: '>=10'}
8037 8044
  8045 + mutation-observer@1.0.3:
  8046 + resolution: {integrity: sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==}
  8047 +
8038 mz@2.7.0: 8048 mz@2.7.0:
8039 resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 8049 resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
8040 8050
@@ -10288,6 +10298,9 @@ packages: @@ -10288,6 +10298,9 @@ packages:
10288 resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==} 10298 resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==}
10289 engines: {node: '>= 0.10'} 10299 engines: {node: '>= 0.10'}
10290 10300
  10301 + vconsole@3.15.1:
  10302 + resolution: {integrity: sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==}
  10303 +
10291 vdirs@0.1.8: 10304 vdirs@0.1.8:
10292 resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} 10305 resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==}
10293 peerDependencies: 10306 peerDependencies:
@@ -15023,6 +15036,8 @@ snapshots: @@ -15023,6 +15036,8 @@ snapshots:
15023 dependencies: 15036 dependencies:
15024 is-what: 5.5.0 15037 is-what: 5.5.0
15025 15038
  15039 + copy-text-to-clipboard@3.2.2: {}
  15040 +
15026 core-js-compat@3.46.0: 15041 core-js-compat@3.46.0:
15027 dependencies: 15042 dependencies:
15028 browserslist: 4.28.0 15043 browserslist: 4.28.0
@@ -17462,6 +17477,8 @@ snapshots: @@ -17462,6 +17477,8 @@ snapshots:
17462 arrify: 2.0.1 17477 arrify: 2.0.1
17463 minimatch: 3.1.2 17478 minimatch: 3.1.2
17464 17479
  17480 + mutation-observer@1.0.3: {}
  17481 +
17465 mz@2.7.0: 17482 mz@2.7.0:
17466 dependencies: 17483 dependencies:
17467 any-promise: 1.3.0 17484 any-promise: 1.3.0
@@ -19917,6 +19934,13 @@ snapshots: @@ -19917,6 +19934,13 @@ snapshots:
19917 19934
19918 validator@13.15.23: {} 19935 validator@13.15.23: {}
19919 19936
  19937 + vconsole@3.15.1:
  19938 + dependencies:
  19939 + '@babel/runtime': 7.28.4
  19940 + copy-text-to-clipboard: 3.2.2
  19941 + core-js: 3.46.0
  19942 + mutation-observer: 1.0.3
  19943 +
19920 vdirs@0.1.8(vue@3.5.24(typescript@5.9.3)): 19944 vdirs@0.1.8(vue@3.5.24(typescript@5.9.3)):
19921 dependencies: 19945 dependencies:
19922 evtd: 0.2.4 19946 evtd: 0.2.4