Commit 4477f605da7ff298d6199eaf0454792ecfdeb6ac

Authored by tianwu
1 parent cec216f8

更改打包配置

apps/web-payment/.env.production
1   -VITE_BASE=/
  1 +VITE_BASE = /pages/
2 2  
3 3 # 接口地址
4   -VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
  4 +VITE_GLOB_API_URL=http://cashier.test.gszdtop.com
5 5  
6 6 # 是否开启压缩,可以设置为 none, brotli, gzip
7 7 VITE_COMPRESS=none
... ...
apps/web-payment/src/api/payment.ts
... ... @@ -51,3 +51,30 @@ export async function listUserCards(
51 51 `/card/payment/listUserCards?pipelineId=${pipelineId}&userId=${userId}`,
52 52 );
53 53 }
  54 +
  55 +/**
  56 + * 查询支付状态
  57 + * @param paymentId
  58 + * @param mode
  59 + * @returns
  60 + */
  61 +export async function paymentState(paymentId: number | string, mode: 'online') {
  62 + return requestClient.post<any>(
  63 + `/payment/cashier/paymentState?paymentId=${paymentId}&mode=${mode}`,
  64 + );
  65 +}
  66 +
  67 +/**
  68 + * 中瑞特供查询
  69 + * @param paymentId
  70 + * @param mode
  71 + * @returns
  72 + */
  73 +export async function zrPaymentState(
  74 + paymentId: number | string,
  75 + mode: 'online',
  76 +) {
  77 + return requestClient.post<any>(
  78 + `/payment/cashier/zrPaymentState?paymentId=${paymentId}&mode=${mode}`,
  79 + );
  80 +}
... ...
apps/web-payment/src/views/payment/index.vue
... ... @@ -5,6 +5,7 @@ import { useRoute, useRouter } from &#39;vue-router&#39;;
5 5 import { fenToYuan } from '@vben/utils';
6 6  
7 7 import {
  8 + Close,
8 9 CreditCard,
9 10 SuccessFilled,
10 11 Wallet,
... ... @@ -13,7 +14,13 @@ import {
13 14 import { ElButton, ElDialog, ElIcon, ElMessage, ElRadio } from 'element-plus';
14 15 import qs from 'qs';
15 16  
16   -import { getOpenId, listUserCards, orderInfo, orderPayment } from '#/api';
  17 +import {
  18 + getOpenId,
  19 + listUserCards,
  20 + orderInfo,
  21 + orderPayment,
  22 + zrPaymentState,
  23 +} from '#/api';
17 24 import EnvironmentDetector from '#/composables/environmentDetector';
18 25  
19 26 import PasswordInput from './component/PasswordInput.vue';
... ... @@ -49,7 +56,7 @@ const REDIRECT_CHANNEL_ID = 29;
49 56  
50 57 // 检查参数是否有效
51 58 const hasValidParams = computed(() => {
52   - return !!(token.value && code.value);
  59 + return !!(token.value || code.value);
53 60 });
54 61  
55 62 const cardList = ref<Card[]>([]);
... ... @@ -118,28 +125,23 @@ const getPaymentIcon = (channelName: string) =&gt; {
118 125 }
119 126 };
120 127  
121   -const jumpTest = () => {
122   - // jWeixin.miniProgram.redirectTo({
123   - // url: `/packageA/pages/wePay/index?amount=${displayAmount.value}&businessType=3&redirect=${true}`,
124   - // });
125   - router.push({
126   - path: '/paymentSuccess',
127   - query: {
128   - amount: displayAmount.value,
129   - success: 'true',
130   - payType: '园区卡支付',
131   - },
132   - });
  128 +// 判断是否是园区卡支付
  129 +const isCardPayment = (pipeline: Pipeline) => {
  130 + const channelName = pipeline.channelName.toLowerCase();
  131 + return channelName.includes('园区卡') || channelName.includes('卡');
133 132 };
134 133  
135 134 // 获取支付方式描述
136 135 const getPaymentDesc = (pipeline: Pipeline) => {
  136 + // 只有当前选中的支付方式是园区卡支付,且已选择卡时,才显示卡号
137 137 if (
138 138 pipeline.pipelineId === currentPaymentMethod.value &&
  139 + isCardPayment(pipeline) &&
139 140 selectedCard.value
140 141 ) {
141 142 return `卡号:${selectedCard.value.cardNo}`;
142 143 }
  144 +
143 145 const channelName = pipeline.channelName.toLowerCase();
144 146 if (channelName.includes('微信')) {
145 147 return '推荐使用';
... ... @@ -181,6 +183,9 @@ const handlepayBtnShowClick = async (pipeline: Pipeline) =&gt; {
181 183 }
182 184 showCardDialog.value = true;
183 185 } else {
  186 + // 切换到其他支付方式时,清空已选择的园区卡
  187 + selectedCard.value = null;
  188 +
184 189 if (pipeline.channelId === REDIRECT_CHANNEL_ID) {
185 190 payBtnShow.value = true;
186 191 return;
... ... @@ -192,7 +197,7 @@ const handlepayBtnShowClick = async (pipeline: Pipeline) =&gt; {
192 197 const handleCardSelect = (card: Card) => {
193 198 selectedCard.value = card;
194 199 showCardDialog.value = false;
195   - ElMessage.success(`已选择 ${card.name} 的园区卡`);
  200 + // ElMessage.success(`已选择 ${card.name} 的园区卡`);
196 201 payBtnShow.value = true;
197 202 };
198 203  
... ... @@ -203,7 +208,6 @@ const handlePasswordCancel = () =&gt; {
203 208 };
204 209  
205 210 const handlePasswordComplete = async (password: string) => {
206   - showPasswordDialog.value = false;
207 211 try {
208 212 const params = {
209 213 tradeId: orderInfoData.value.tradeId,
... ... @@ -216,14 +220,17 @@ const handlePasswordComplete = async (password: string) =&gt; {
216 220 };
217 221  
218 222 const data = await orderPayment(params);
219   - router.push({
220   - path: '/paymentSuccess',
221   - query: {
222   - amount: displayAmount.value,
223   - success: 'true',
224   - payType: '园区卡支付',
225   - },
226   - });
  223 + // 园区卡支付成功开始轮询结果
  224 + checkPayResult(data.paymentId);
  225 + // router.push({
  226 + // path: '/paymentSuccess',
  227 + // query: {
  228 + // amount: displayAmount.value,
  229 + // payee: orderInfoData.value.mchName,
  230 + // success: 'true',
  231 + // payType: '园区卡支付',
  232 + // },
  233 + // });
227 234 } catch (error) {
228 235 errorMessage.value = error?.message || '支付失败';
229 236 payErrorDialog.value = true;
... ... @@ -251,11 +258,10 @@ const queryPayment = async () =&gt; {
251 258 payType: currentPayType.value.channelName,
252 259 redirect: true,
253 260 payee: orderInfoData.value.mchName,
254   - redirectUrl: orderInfoData.value.redirectUrl,
255 261 };
256 262 const queryString = qs.stringify(params);
257 263 if (typeof jWeixin !== 'undefined' && jWeixin.miniProgram) {
258   - jWeixin.miniProgram.navigateTo({
  264 + jWeixin.miniProgram.redirectTo({
259 265 url: `/packageA/pages/wxPay/index?${queryString}`,
260 266 });
261 267 loading.value = false;
... ... @@ -276,7 +282,6 @@ const queryPayment = async () =&gt; {
276 282 goods: orderInfoData.value.goods,
277 283 amount: orderInfoData.value.amount,
278 284 payType: currentPayType.value.channelName,
279   - redirectUrl: orderInfoData.value.redirectUrl,
280 285 payee: orderInfoData.value.mchName,
281 286 };
282 287 const queryString = qs.stringify(pramsData);
... ... @@ -312,17 +317,17 @@ const handlePay = async () =&gt; {
312 317 }
313 318  
314 319 const channelName = currentPayType.value.channelName.toLowerCase();
315   - const isCardPayment =
  320 + const isCardPaymentMethod =
316 321 channelName.includes('园区卡') || channelName.includes('卡支付');
317 322  
318   - if (isCardPayment && !selectedCard.value) {
  323 + if (isCardPaymentMethod && !selectedCard.value) {
319 324 ElMessage.warning('请先选择园区卡');
320 325 return;
321 326 }
322 327  
323 328 loading.value = true;
324 329  
325   - if (isCardPayment) {
  330 + if (isCardPaymentMethod) {
326 331 // 园区卡支付逻辑
327 332 try {
328 333 showPasswordDialog.value = true;
... ... @@ -345,6 +350,12 @@ const handleCloseDialog = () =&gt; {
345 350 payBtnShow.value = false;
346 351 };
347 352  
  353 +// 点击遮罩层关闭
  354 +const handleMaskClick = () => {
  355 + showCardDialog.value = false;
  356 + payBtnShow.value = false;
  357 +};
  358 +
348 359 // 获取订单信息 支付方式等数据
349 360 const getOrderInfo = async () => {
350 361 try {
... ... @@ -378,6 +389,86 @@ const getListUserCards = async () =&gt; {
378 389 }
379 390 };
380 391  
  392 +let pollTimer: any = null;
  393 +let pollCount = 0;
  394 +// 最大轮询次数
  395 +const maxPollCount = 30;
  396 +// 轮询间隔(毫秒)
  397 +const pollInterval = 2000;
  398 +
  399 +const stopPollingPayResult = () => {
  400 + showPasswordDialog.value = false;
  401 + if (pollTimer) {
  402 + clearTimeout(pollTimer);
  403 + pollTimer = null;
  404 + }
  405 + pollCount = 0;
  406 +};
  407 +
  408 +const paySuccessHandler = (data: any) => {
  409 + router.replace({
  410 + path: '/paymentSuccess',
  411 + query: {
  412 + amount: displayAmount.value,
  413 + payee: orderInfoData.value.mchName,
  414 + success: 'true',
  415 + payType: '园区卡支付',
  416 + redirectUrl: data.redirectUrl,
  417 + },
  418 + });
  419 +};
  420 +
  421 +const payFailHandler = (msg: any) => {};
  422 +
  423 +const payTimeoutHandler = () => {
  424 + // errorMessage: '支付结果查询超时,请稍后在订单中查看支付状态'
  425 +};
  426 +
  427 +const checkPayResult = async (paymentId: number | string) => {
  428 + try {
  429 + const data = await zrPaymentState(paymentId, 'online');
  430 + if (data?.state === 4) {
  431 + stopPollingPayResult();
  432 + paySuccessHandler(data);
  433 + } else if (data?.state === 6) {
  434 + // 支付失败
  435 + stopPollingPayResult();
  436 + payFailHandler(data?.message || '支付失败');
  437 + } else {
  438 + pollCount++;
  439 + if (pollCount < maxPollCount) {
  440 + pollTimer = setTimeout(() => {
  441 + checkPayResult(paymentId);
  442 + }, pollInterval);
  443 + } else {
  444 + // 超过最大轮询次数,停止轮询
  445 + console.log('支付结果查询超时');
  446 + stopPollingPayResult();
  447 + payTimeoutHandler();
  448 + }
  449 + }
  450 + } catch (error) {
  451 + ElMessage.error(JSON.stringify(error));
  452 + console.error('支付结果查询失败:', error);
  453 + if (error?.code === 'E504') {
  454 + stopPollingPayResult();
  455 + payFailHandler(error?.msg || '支付失败');
  456 + } else {
  457 + // 查询失败,继续轮询
  458 + pollCount++;
  459 +
  460 + if (pollCount < maxPollCount) {
  461 + pollTimer = setTimeout(() => {
  462 + checkPayResult(paymentId);
  463 + }, pollInterval);
  464 + } else {
  465 + stopPollingPayResult();
  466 + payTimeoutHandler();
  467 + }
  468 + }
  469 + }
  470 +};
  471 +
381 472 const init = async () => {
382 473 token.value = (route.query?.token as string) || '';
383 474 openId.value = (route.query?.openId as string) || '';
... ... @@ -547,39 +638,51 @@ init();
547 638 </div>
548 639 </div>
549 640  
550   - <!-- 园区卡选择弹窗 -->
551   - <ElDialog
552   - v-model="showCardDialog"
553   - title="选择园区卡"
554   - width="90%"
555   - :style="{ maxWidth: '500px' }"
556   - class="card-dialog"
557   - :close-on-click-modal="false"
558   - >
559   - <div class="card-list-dialog">
560   - <div
561   - v-for="card in cardList"
562   - :key="card.cardNo"
563   - class="card-item-dialog"
564   - @click="handleCardSelect(card)"
565   - >
566   - <div class="card-item-info">
567   - <p class="card-holder">{{ card.name }}</p>
568   - <p class="card-number">{{ card.cardNo }}</p>
  641 + <!-- 园区卡选择底部弹出层 -->
  642 + <transition name="fade">
  643 + <div
  644 + v-if="showCardDialog"
  645 + class="bottom-sheet-mask"
  646 + @click="handleMaskClick"
  647 + ></div>
  648 + </transition>
  649 + <transition name="slide-up">
  650 + <div v-if="showCardDialog" class="bottom-sheet">
  651 + <div class="bottom-sheet-header">
  652 + <h3 class="bottom-sheet-title">选择园区卡</h3>
  653 + <div class="bottom-sheet-close" @click="handleCloseDialog">
  654 + <ElIcon :size="24" color="#6b7280">
  655 + <Close />
  656 + </ElIcon>
569 657 </div>
570   - <div class="card-balance">
571   - <p class="balance-label">余额</p>
572   - <p class="balance-value">¥{{ card.amount }}</p>
  658 + </div>
  659 + <div class="bottom-sheet-body">
  660 + <div class="card-list">
  661 + <div
  662 + v-for="card in cardList"
  663 + :key="card.cardNo"
  664 + class="card-item"
  665 + @click="handleCardSelect(card)"
  666 + >
  667 + <div class="card-item-info">
  668 + <p class="card-holder">{{ card.name }}</p>
  669 + <p class="card-number">{{ card.cardNo }}</p>
  670 + </div>
  671 + <div class="card-balance">
  672 + <p class="balance-label">余额</p>
  673 + <p class="balance-value">¥{{ fenToYuan(card.amount) }}</p>
  674 + </div>
  675 + </div>
  676 + <div v-if="cardList.length === 0" class="empty-card">
  677 + <p>暂无可用园区卡</p>
  678 + </div>
573 679 </div>
574 680 </div>
575   - <div v-if="cardList.length === 0" class="empty-card">
576   - <p>暂无可用园区卡</p>
  681 + <div class="bottom-sheet-footer">
  682 + <button class="cancel-button" @click="handleCloseDialog">取消</button>
577 683 </div>
578 684 </div>
579   - <template #footer>
580   - <ElButton @click="handleCloseDialog">取消</ElButton>
581   - </template>
582   - </ElDialog>
  685 + </transition>
583 686  
584 687 <ElDialog
585 688 v-model="payErrorDialog"
... ... @@ -680,6 +783,28 @@ init();
680 783 }
681 784 }
682 785  
  786 +// 遮罩层动画
  787 +.fade-enter-active,
  788 +.fade-leave-active {
  789 + transition: opacity 0.3s ease;
  790 +}
  791 +
  792 +.fade-enter-from,
  793 +.fade-leave-to {
  794 + opacity: 0;
  795 +}
  796 +
  797 +// 底部弹出动画
  798 +.slide-up-enter-active,
  799 +.slide-up-leave-active {
  800 + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  801 +}
  802 +
  803 +.slide-up-enter-from,
  804 +.slide-up-leave-to {
  805 + transform: translateY(100%);
  806 +}
  807 +
683 808 .cashier-container {
684 809 min-height: 100vh;
685 810 background: linear-gradient(
... ... @@ -994,90 +1119,201 @@ init();
994 1119 }
995 1120 }
996 1121  
997   -// 园区卡选择弹窗
998   -.card-dialog {
999   - :deep(.el-dialog__header) {
1000   - padding: 20px 24px;
  1122 +// 底部弹出层样式
  1123 +.bottom-sheet-mask {
  1124 + position: fixed;
  1125 + inset: 0;
  1126 + z-index: 1000;
  1127 + background-color: rgb(0 0 0 / 50%);
  1128 +}
  1129 +
  1130 +.bottom-sheet {
  1131 + position: fixed;
  1132 + right: 0;
  1133 + bottom: 0;
  1134 + left: 0;
  1135 + z-index: 1001;
  1136 + display: flex;
  1137 + flex-direction: column;
  1138 + max-height: 70vh;
  1139 + background: #fff;
  1140 + border-radius: 16px 16px 0 0;
  1141 + box-shadow: 0 -4px 20px rgb(0 0 0 / 10%);
  1142 +
  1143 + .bottom-sheet-header {
  1144 + display: flex;
  1145 + flex-shrink: 0;
  1146 + align-items: center;
  1147 + justify-content: space-between;
  1148 + padding: 20px 24px 16px;
1001 1149 border-bottom: 1px solid #f0f0f0;
1002   - }
1003 1150  
1004   - :deep(.el-dialog__title) {
1005   - font-size: 18px;
1006   - font-weight: 600;
1007   - color: #1f2937;
  1151 + .bottom-sheet-title {
  1152 + margin: 0;
  1153 + font-size: 18px;
  1154 + font-weight: 600;
  1155 + color: #1f2937;
  1156 + }
  1157 +
  1158 + .bottom-sheet-close {
  1159 + display: flex;
  1160 + align-items: center;
  1161 + justify-content: center;
  1162 + width: 32px;
  1163 + height: 32px;
  1164 + cursor: pointer;
  1165 + border-radius: 50%;
  1166 + transition: background-color 0.2s;
  1167 +
  1168 + &:hover {
  1169 + background-color: #f3f4f6;
  1170 + }
  1171 +
  1172 + &:active {
  1173 + background-color: #e5e7eb;
  1174 + }
  1175 + }
1008 1176 }
1009 1177  
1010   - :deep(.el-dialog__body) {
1011   - padding: 24px;
  1178 + .bottom-sheet-body {
  1179 + flex: 1;
  1180 + overflow: hidden;
1012 1181 }
1013   -}
1014 1182  
1015   -.card-list-dialog {
1016   - display: flex;
1017   - flex-direction: column;
1018   - gap: 12px;
1019   - max-height: 400px;
1020   - overflow-y: auto;
  1183 + .card-list {
  1184 + display: flex;
  1185 + flex-direction: column;
  1186 + gap: 12px;
  1187 + max-height: calc(70vh - 160px);
  1188 + padding: 36px 24px;
  1189 + overflow-y: auto;
  1190 + -webkit-overflow-scrolling: touch;
  1191 +
  1192 + &::-webkit-scrollbar {
  1193 + width: 4px;
  1194 + }
1021 1195  
1022   - .empty-card {
1023   - padding: 40px 20px;
1024   - color: #9ca3af;
1025   - text-align: center;
1026   - }
1027   -}
  1196 + &::-webkit-scrollbar-thumb {
  1197 + background-color: rgb(0 0 0 / 20%);
  1198 + border-radius: 2px;
  1199 + }
1028 1200  
1029   -.card-item-dialog {
1030   - display: flex;
1031   - align-items: center;
1032   - justify-content: space-between;
1033   - padding: 16px;
1034   - cursor: pointer;
1035   - background: linear-gradient(135deg, #f0fdf4 0%, #d1fae5 100%);
1036   - border: 2px solid transparent;
1037   - border-radius: 12px;
1038   - transition: all 0.3s ease;
1039   -
1040   - &:hover {
1041   - background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
1042   - border-color: #10b981;
1043   - box-shadow: 0 4px 12px rgb(16 185 129 / 20%);
1044   - transform: translateY(-2px);
  1201 + &::-webkit-scrollbar-track {
  1202 + background-color: transparent;
  1203 + }
  1204 +
  1205 + .empty-card {
  1206 + padding: 40px 20px;
  1207 + color: #9ca3af;
  1208 + text-align: center;
  1209 + }
1045 1210 }
1046 1211  
1047   - .card-item-info {
1048   - .card-holder {
1049   - margin: 0 0 4px;
1050   - font-size: 16px;
1051   - font-weight: 600;
1052   - color: #1f2937;
  1212 + .card-item {
  1213 + display: flex;
  1214 + flex-shrink: 0;
  1215 + align-items: center;
  1216 + justify-content: space-between;
  1217 + padding: 16px;
  1218 + cursor: pointer;
  1219 + background: #fff;
  1220 + border: 2px solid #f0f0f0;
  1221 + border-radius: 12px;
  1222 + transition: all 0.3s ease;
  1223 +
  1224 + &:hover {
  1225 + background: linear-gradient(135deg, #fff9f1 0%, #ffe9d4 100%);
  1226 + border-color: #ea4200;
  1227 + box-shadow: 0 4px 12px rgb(234 66 0 / 20%);
  1228 + transform: translateY(-2px);
1053 1229 }
1054 1230  
1055   - .card-number {
1056   - margin: 0;
1057   - font-family: 'Courier New', monospace;
1058   - font-size: 13px;
1059   - color: #6b7280;
  1231 + &:active {
  1232 + background: linear-gradient(135deg, #ffe9d4 0%, #ffd9b8 100%);
  1233 + transform: translateY(0);
  1234 + }
  1235 +
  1236 + .card-item-info {
  1237 + .card-holder {
  1238 + margin: 0 0 4px;
  1239 + font-size: 16px;
  1240 + font-weight: 600;
  1241 + color: #1f2937;
  1242 + }
  1243 +
  1244 + .card-number {
  1245 + margin: 0;
  1246 + font-family: 'Courier New', monospace;
  1247 + font-size: 16px;
  1248 + color: #6b7280;
  1249 + }
  1250 + }
  1251 +
  1252 + .card-balance {
  1253 + text-align: right;
  1254 +
  1255 + .balance-label {
  1256 + margin: 0 0 4px;
  1257 + font-size: 12px;
  1258 + color: #6b7280;
  1259 + }
  1260 +
  1261 + .balance-value {
  1262 + margin: 0;
  1263 + font-size: 18px;
  1264 + font-weight: bold;
  1265 + color: #ea4200;
  1266 + }
1060 1267 }
1061 1268 }
1062 1269  
1063   - .card-balance {
1064   - text-align: right;
  1270 + .bottom-sheet-footer {
  1271 + flex-shrink: 0;
  1272 + padding: 16px 24px;
  1273 + padding-bottom: calc(16px + env(safe-area-inset-bottom));
  1274 + border-top: 1px solid #f0f0f0;
1065 1275  
1066   - .balance-label {
1067   - margin: 0 0 4px;
1068   - font-size: 12px;
  1276 + .cancel-button {
  1277 + width: 100%;
  1278 + height: 44px;
  1279 + font-size: 16px;
  1280 + font-weight: 600;
1069 1281 color: #6b7280;
1070   - }
  1282 + cursor: pointer;
  1283 + background: #f3f4f6;
  1284 + border: none;
  1285 + border-radius: 8px;
  1286 + transition: all 0.2s;
  1287 +
  1288 + &:hover {
  1289 + background: #e5e7eb;
  1290 + }
1071 1291  
1072   - .balance-value {
1073   - margin: 0;
1074   - font-size: 18px;
1075   - font-weight: bold;
1076   - color: #10b981;
  1292 + &:active {
  1293 + transform: scale(0.98);
  1294 + }
1077 1295 }
1078 1296 }
1079 1297 }
1080 1298  
  1299 +// 原有的card-dialog样式(用于错误提示弹窗)
  1300 +.card-dialog {
  1301 + :deep(.el-dialog__header) {
  1302 + padding: 20px 24px;
  1303 + border-bottom: 1px solid #f0f0f0;
  1304 + }
  1305 +
  1306 + :deep(.el-dialog__title) {
  1307 + font-size: 18px;
  1308 + font-weight: 600;
  1309 + color: #1f2937;
  1310 + }
  1311 +
  1312 + :deep(.el-dialog__body) {
  1313 + padding: 24px;
  1314 + }
  1315 +}
  1316 +
1081 1317 // 成功对话框
1082 1318 .success-dialog {
1083 1319 :deep(.el-dialog__body) {
... ...
apps/web-payment/src/views/payment/paySuccess.vue
... ... @@ -16,7 +16,9 @@ const init = async () =&gt; {
16 16 };
17 17  
18 18 const handleBack = () => {
19   - if (
  19 + if (queryData.value.redirectUrl) {
  20 + window.location.href = queryData.value.redirectUrl;
  21 + } else if (
20 22 typeof jWeixin !== 'undefined' &&
21 23 jWeixin.miniProgram &&
22 24 detector.value?.env.isMiniProgram
... ... @@ -25,6 +27,15 @@ const handleBack = () =&gt; {
25 27 url: `/pages/newhome/newhome`,
26 28 });
27 29 }
  30 + // if (
  31 + // typeof jWeixin !== 'undefined' &&
  32 + // jWeixin.miniProgram &&
  33 + // detector.value?.env.isMiniProgram
  34 + // ) {
  35 + // jWeixin.miniProgram.switchTab({
  36 + // url: `/pages/newhome/newhome`,
  37 + // });
  38 + // }
28 39 };
29 40  
30 41 onMounted(() => {
... ... @@ -35,7 +46,6 @@ onMounted(() =&gt; {
35 46  
36 47 <template>
37 48 <div class="cashier-container" v-loading="loadLoading">
38   - {{ detector?.env }}
39 49 <!-- 正常支付界面 -->
40 50 <div class="cashier-wrapper">
41 51 <div class="pt-[40px]">
... ... @@ -52,6 +62,12 @@ onMounted(() =&gt; {
52 62 <div>支付金额</div>
53 63 <div>{{ queryData?.amount }} 元</div>
54 64 </div>
  65 + <div class="flex justify-between">
  66 + <div>收款方</div>
  67 + <div class="w-[70%] break-words">
  68 + {{ queryData?.payee }}
  69 + </div>
  70 + </div>
55 71 <div class="mt-10 flex justify-between">
56 72 <ElButton
57 73 class="pay-button"
... ...
apps/web-payment/vite.config.mts
... ... @@ -6,6 +6,7 @@ export default defineConfig(async () =&gt; {
6 6 return {
7 7 application: {},
8 8 vite: {
  9 + base: '/pages/',
9 10 plugins: [
10 11 ElementPlus({
11 12 format: 'esm',
... ... @@ -17,7 +18,7 @@ export default defineConfig(async () =&gt; {
17 18 changeOrigin: true,
18 19 rewrite: (path) => path.replace(/^\/api/, ''),
19 20 // mock代理目标地址
20   - target: 'http://10.28.3.34:8686',
  21 + target: 'http://cashier.test.gszdtop.com',
21 22 ws: true,
22 23 },
23 24 },
... ...