提示文案处理
This commit is contained in:
parent
2cd97322df
commit
71c8ed68b3
@ -4,7 +4,7 @@ VITE_API_BASE_URL=https://api.likeichat.com
|
|||||||
VITE_APP_TITLE=Likei H5 (Development)
|
VITE_APP_TITLE=Likei H5 (Development)
|
||||||
|
|
||||||
# 普通用户
|
# 普通用户
|
||||||
VITE_USER_AUTH=03FF1925725628BD5319BAF8CAC4B1C8.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4MTgwNjE1ODAxJTNBMTc1NTU4ODYxNTgwMQ==
|
VITE_USER_AUTH=657DB83B46ED88A0384D8FA9D83C1BA7.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4Mjc1MTUwMzQ2JTNBMTc1NTY4MzE1MDM0Ng==
|
||||||
|
|
||||||
# 代理用户 8826603
|
# 代理用户 8826603
|
||||||
# VITE_USER_AUTH=747E27BE38B21A129CE41BB1F80EA924.djIlM0ExOTU3MzU2MTM4NTIzMDY2MzY5JTNBTElLRUklM0ExNzU4MDk3MDg4NDA0JTNBMTc1NTUwNTA4ODQwNA==
|
# VITE_USER_AUTH=747E27BE38B21A129CE41BB1F80EA924.djIlM0ExOTU3MzU2MTM4NTIzMDY2MzY5JTNBTElLRUklM0ExNzU4MDk3MDg4NDA0JTNBMTc1NTUwNTA4ODQwNA==
|
||||||
|
|||||||
255
src/components/Toast.vue
Normal file
255
src/components/Toast.vue
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="visible" class="error-modal-overlay" @click="handleOverlayClick">
|
||||||
|
<div class="error-modal" :class="animationClass">
|
||||||
|
<!-- 错误图标 -->
|
||||||
|
<div class="error-icon">
|
||||||
|
<div class="error-circle">
|
||||||
|
<span class="error-x">✕</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="error-title" v-if="title">{{ title }}</div>
|
||||||
|
|
||||||
|
<!-- 错误信息 -->
|
||||||
|
<div class="error-message">{{ message }}</div>
|
||||||
|
|
||||||
|
<!-- 按钮 -->
|
||||||
|
<div class="error-actions">
|
||||||
|
<button class="error-btn" @click="confirm">{{ confirmText }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: 'Error'
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: 'OK'
|
||||||
|
},
|
||||||
|
clickToClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['confirm', 'close'])
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const animationClass = ref('')
|
||||||
|
|
||||||
|
const show = () => {
|
||||||
|
visible.value = true
|
||||||
|
animationClass.value = 'modal-enter'
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
animationClass.value = 'modal-leave'
|
||||||
|
setTimeout(() => {
|
||||||
|
visible.value = false
|
||||||
|
emit('close')
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = () => {
|
||||||
|
emit('confirm')
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOverlayClick = () => {
|
||||||
|
if (props.clickToClose) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时显示
|
||||||
|
onMounted(() => {
|
||||||
|
show()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
close
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.error-modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-modal {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 320px;
|
||||||
|
padding: 24px 20px 20px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 错误图标 */
|
||||||
|
.error-icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-circle {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #FEE2E2;
|
||||||
|
border: 3px solid #FECACA;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
animation: errorPulse 0.6s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-x {
|
||||||
|
color: #DC2626;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题 */
|
||||||
|
.error-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1F2937;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 错误信息 */
|
||||||
|
.error-message {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6B7280;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮区域 */
|
||||||
|
.error-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-btn {
|
||||||
|
background-color: #DC2626;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 32px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-btn:hover {
|
||||||
|
background-color: #B91C1C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-btn:active {
|
||||||
|
background-color: #991B1B;
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 动画效果 */
|
||||||
|
.modal-enter {
|
||||||
|
animation: modalEnter 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-leave {
|
||||||
|
animation: modalLeave 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalEnter {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.7) translateY(-10px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalLeave {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9) translateY(-5px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes errorPulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.error-modal {
|
||||||
|
max-width: 280px;
|
||||||
|
padding: 20px 16px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-circle {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-x {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-title {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
106
src/utils/toast.js
Normal file
106
src/utils/toast.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import ErrorModal from '../components/Toast.vue'
|
||||||
|
|
||||||
|
class ErrorModalManager {
|
||||||
|
constructor() {
|
||||||
|
this.instances = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示错误弹框
|
||||||
|
show(message, options = {}) {
|
||||||
|
const container = document.createElement('div')
|
||||||
|
document.body.appendChild(container)
|
||||||
|
|
||||||
|
const app = createApp(ErrorModal, {
|
||||||
|
message,
|
||||||
|
...options,
|
||||||
|
onConfirm: () => {
|
||||||
|
if (options.onConfirm) {
|
||||||
|
options.onConfirm()
|
||||||
|
}
|
||||||
|
this.cleanup(app, container)
|
||||||
|
},
|
||||||
|
onClose: () => {
|
||||||
|
if (options.onClose) {
|
||||||
|
options.onClose()
|
||||||
|
}
|
||||||
|
this.cleanup(app, container)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const instance = app.mount(container)
|
||||||
|
this.instances.push(app)
|
||||||
|
|
||||||
|
return {
|
||||||
|
close: () => instance.close(),
|
||||||
|
instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理DOM和实例
|
||||||
|
cleanup(app, container) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (container && container.parentNode) {
|
||||||
|
container.parentNode.removeChild(container)
|
||||||
|
}
|
||||||
|
app.unmount()
|
||||||
|
|
||||||
|
// 从实例列表中移除
|
||||||
|
const index = this.instances.indexOf(app)
|
||||||
|
if (index > -1) {
|
||||||
|
this.instances.splice(index, 1)
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭所有弹框
|
||||||
|
closeAll() {
|
||||||
|
this.instances.forEach(app => {
|
||||||
|
const instance = app._instance
|
||||||
|
if (instance && instance.exposed && instance.exposed.close) {
|
||||||
|
instance.exposed.close()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.instances = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建全局实例
|
||||||
|
export const errorModal = new ErrorModalManager()
|
||||||
|
|
||||||
|
// 快捷方法 - 替代alert
|
||||||
|
export const showError = (message, title = 'Error') => {
|
||||||
|
return errorModal.show(message, { title })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 错误处理的专用方法
|
||||||
|
export const handleError = (error) => {
|
||||||
|
let message = 'An unknown error occurred'
|
||||||
|
let title = 'Error'
|
||||||
|
|
||||||
|
if (error.errorCode === 1083) {
|
||||||
|
title = 'Service Unavailable'
|
||||||
|
message = 'Exchange function is not available'
|
||||||
|
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
||||||
|
title = 'Request Not Acceptable'
|
||||||
|
message = 'Something went wrong, please retry.'
|
||||||
|
} else if (error.message) {
|
||||||
|
message = error.message
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorModal.show(message, { title })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认对话框
|
||||||
|
export const showConfirm = (message, title = 'Confirm') => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
errorModal.show(message, {
|
||||||
|
title,
|
||||||
|
confirmText: 'Confirm',
|
||||||
|
onConfirm: () => resolve(true),
|
||||||
|
onClose: () => resolve(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default errorModal
|
||||||
@ -157,6 +157,7 @@ import MobileHeader from '../components/MobileHeader.vue'
|
|||||||
import { get } from '../utils/http.js'
|
import { get } from '../utils/http.js'
|
||||||
import {getBankBalance} from "@/api/wallet.js";
|
import {getBankBalance} from "@/api/wallet.js";
|
||||||
import {getTeamId} from "@/utils/userStore.js";
|
import {getTeamId} from "@/utils/userStore.js";
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -266,7 +267,7 @@ const fetchBankBalance = async () => {
|
|||||||
console.error('Failed to fetch bank balance:', error)
|
console.error('Failed to fetch bank balance:', error)
|
||||||
salaryInfo.currentSalary = 0.00
|
salaryInfo.currentSalary = 0.00
|
||||||
// 可以显示错误提示
|
// 可以显示错误提示
|
||||||
alert('Failed to load balance. Please try again.')
|
showError('Failed to load balance. Please try again.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@
|
|||||||
<span class="record-status status-pending">
|
<span class="record-status status-pending">
|
||||||
Pending
|
Pending
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="cancel-btn"
|
class="cancel-btn"
|
||||||
@click="handleCancelApply(record)"
|
@click="handleCancelApply(record)"
|
||||||
>
|
>
|
||||||
@ -96,6 +96,7 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { sendTeamApplyJoin, getWaitApplyRecord, cancelApply } from '../api/wallet.js'
|
import { sendTeamApplyJoin, getWaitApplyRecord, cancelApply } from '../api/wallet.js'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -124,20 +125,20 @@ const handleCancelApply = async (record) => {
|
|||||||
if (!confirm('确定要撤销这个申请吗?')) {
|
if (!confirm('确定要撤销这个申请吗?')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await cancelApply(record.messageId)
|
const response = await cancelApply(record.messageId)
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
alert('撤销成功!')
|
showError('撤销成功!')
|
||||||
// 刷新申请记录
|
// 刷新申请记录
|
||||||
applyRecords.value = [] // 清空记录
|
applyRecords.value = [] // 清空记录
|
||||||
await fetchApplyRecords()
|
await fetchApplyRecords()
|
||||||
} else {
|
} else {
|
||||||
alert(response.message || '撤销失败,请重试')
|
showError(response.message || '撤销失败,请重试')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('撤销申请失败:', error)
|
console.error('撤销申请失败:', error)
|
||||||
alert('撤销失败,请重试')
|
showError('撤销失败,请重试')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ const submitApplication = async () => {
|
|||||||
const response = await sendTeamApplyJoin(applicationData)
|
const response = await sendTeamApplyJoin(applicationData)
|
||||||
|
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
alert('Application submitted successfully!')
|
showError('Application submitted successfully!')
|
||||||
await fetchApplyRecords() // 刷新申请记录
|
await fetchApplyRecords() // 刷新申请记录
|
||||||
agentId.value = '' // 清空输入
|
agentId.value = '' // 清空输入
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -98,6 +98,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { getSelectedUser, clearSelectedUser } from '../utils/coinSellerStore.js'
|
import { getSelectedUser, clearSelectedUser } from '../utils/coinSellerStore.js'
|
||||||
import { checkFreightDealer, getTeamEntry, getFreightBalance, searchFreightUser, freightRecharge } from '../api/wallet.js'
|
import { checkFreightDealer, getTeamEntry, getFreightBalance, searchFreightUser, freightRecharge } from '../api/wallet.js'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ const checkDealerAccess = async () => {
|
|||||||
|
|
||||||
if (!dealerAccess.value) {
|
if (!dealerAccess.value) {
|
||||||
// 没有权限,跳转回上一页或首页
|
// 没有权限,跳转回上一页或首页
|
||||||
alert('您没有金币销售商权限')
|
showError('您没有金币销售商权限')
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -223,14 +224,14 @@ const rechargeNow = async () => {
|
|||||||
|
|
||||||
const amount = parseFloat(rechargeAmount.value)
|
const amount = parseFloat(rechargeAmount.value)
|
||||||
if (amount <= 0) {
|
if (amount <= 0) {
|
||||||
alert('请输入正确的充值金额')
|
showError('请输入正确的充值金额')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 需要获取接收用户的ID(从用户搜索结果中获取)
|
// 需要获取接收用户的ID(从用户搜索结果中获取)
|
||||||
const acceptUserId = selectedUser.value.userId || selectedUser.value.id
|
const acceptUserId = selectedUser.value.userId || selectedUser.value.id
|
||||||
if (!acceptUserId) {
|
if (!acceptUserId) {
|
||||||
alert('无法获取用户ID,请重新选择用户')
|
showError('无法获取用户ID,请重新选择用户')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,16 +251,16 @@ const rechargeNow = async () => {
|
|||||||
coinsAmount.value = response.body.toString()
|
coinsAmount.value = response.body.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
alert(`成功向 ${selectedUser.value.name} 充值 ${amount} 金币`)
|
showError(`成功向 ${selectedUser.value.name} 充值 ${amount} 金币`)
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
rechargeAmount.value = ''
|
rechargeAmount.value = ''
|
||||||
} else {
|
} else {
|
||||||
alert('充值失败,请重试')
|
showError('充值失败,请重试')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('充值失败:', error)
|
console.error('充值失败:', error)
|
||||||
alert('充值失败,请检查网络后重试')
|
showError('充值失败,请检查网络后重试')
|
||||||
} finally {
|
} finally {
|
||||||
isRecharging.value = false
|
isRecharging.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,7 @@ import { ref, reactive, onMounted } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { getBankBalance, userSalaryCheckExchange, userBankExchangeGold } from '../api/wallet.js'
|
import { getBankBalance, userSalaryCheckExchange, userBankExchangeGold } from '../api/wallet.js'
|
||||||
|
import { showError } from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ const fetchBankBalance = async () => {
|
|||||||
console.error('Failed to fetch bank balance:', error)
|
console.error('Failed to fetch bank balance:', error)
|
||||||
availableSalary.value = '0.00'
|
availableSalary.value = '0.00'
|
||||||
// 可以显示错误提示
|
// 可以显示错误提示
|
||||||
alert('Failed to load balance. Please try again.')
|
showError('Failed to load balance. Please try again.')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -125,13 +126,13 @@ const checkUserRole = async () => {
|
|||||||
// 处理特定错误情况
|
// 处理特定错误情况
|
||||||
if (error.errorCode === 1083) {
|
if (error.errorCode === 1083) {
|
||||||
// NOT_OPEN_ERROR
|
// NOT_OPEN_ERROR
|
||||||
alert('Exchange function is not available')
|
showError('Exchange function is not available')
|
||||||
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
||||||
// 处理 406 Not Acceptable 状态码
|
// 处理 406 Not Acceptable 状态码
|
||||||
alert('The server cannot produce a response matching the list of acceptable values defined in the request headers')
|
showError('The server cannot produce a response matching the list of acceptable values defined in the request headers')
|
||||||
} else {
|
} else {
|
||||||
// 其他错误情况
|
// 其他错误情况
|
||||||
alert('Failed to load user information')
|
showError('Failed to load user information')
|
||||||
}
|
}
|
||||||
router.back() // 对于其他严重错误,也建议退出页面
|
router.back() // 对于其他严重错误,也建议退出页面
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ const checkUserRole = async () => {
|
|||||||
|
|
||||||
const exchangeCoins = async () => {
|
const exchangeCoins = async () => {
|
||||||
if (!selectedCoin.value) {
|
if (!selectedCoin.value) {
|
||||||
alert('Please select a coin amount first')
|
showError('Please select a coin amount first')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +157,7 @@ const exchangeCoins = async () => {
|
|||||||
const availableBalance = parseFloat(availableSalary.value)
|
const availableBalance = parseFloat(availableSalary.value)
|
||||||
|
|
||||||
if (isNaN(availableBalance) || availableBalance < coinPrice) {
|
if (isNaN(availableBalance) || availableBalance < coinPrice) {
|
||||||
alert(`Insufficient balance. Your current balance is $${availableBalance.toFixed(2)}, but you need $${coinPrice} to exchange.`)
|
showError(`Insufficient balance. Your current balance is $${availableBalance.toFixed(2)}, but you need $${coinPrice} to exchange.`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ const exchangeCoins = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (response.status === true || response.errorCode === 0) {
|
if (response.status === true || response.errorCode === 0) {
|
||||||
alert(`Successfully exchanged ${selectedCoinData.amount} coins for $${selectedCoinData.price}`)
|
showError(`Successfully exchanged ${selectedCoinData.amount} coins for $${selectedCoinData.price}`)
|
||||||
|
|
||||||
// 刷新银行余额
|
// 刷新银行余额
|
||||||
await fetchBankBalance()
|
await fetchBankBalance()
|
||||||
@ -184,11 +185,11 @@ const exchangeCoins = async () => {
|
|||||||
} else {
|
} else {
|
||||||
// 接口调用失败
|
// 接口调用失败
|
||||||
const errorMessage = response.message || 'Exchange failed, please try again later.'
|
const errorMessage = response.message || 'Exchange failed, please try again later.'
|
||||||
alert(errorMessage)
|
showError(errorMessage)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Exchange error:', error)
|
console.error('Exchange error:', error)
|
||||||
alert('An error occurred during the exchange process. Please try again later.')
|
showError('An error occurred during the exchange process. Please try again later.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果用户取消,则什么都不做
|
// 如果用户取消,则什么都不做
|
||||||
|
|||||||
@ -130,6 +130,7 @@ import MobileHeader from '../components/MobileHeader.vue'
|
|||||||
import { getBankBalance, getUserIdentity, getTeamEntry, getTeamMemberWorkStatistics } from '../api/wallet.js'
|
import { getBankBalance, getUserIdentity, getTeamEntry, getTeamMemberWorkStatistics } from '../api/wallet.js'
|
||||||
import { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp } from '../utils/appBridge.js'
|
import { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp } from '../utils/appBridge.js'
|
||||||
import {getUserId, setUserInfo} from '../utils/userStore.js'
|
import {getUserId, setUserInfo} from '../utils/userStore.js'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -223,7 +224,7 @@ const fetchBankBalance = async () => {
|
|||||||
console.error('Failed to fetch bank balance:', error)
|
console.error('Failed to fetch bank balance:', error)
|
||||||
salaryInfo.currentSalary = 0.00
|
salaryInfo.currentSalary = 0.00
|
||||||
// 可以显示错误提示
|
// 可以显示错误提示
|
||||||
alert('Failed to load balance. Please try again.')
|
showError('Failed to load balance. Please try again.')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<h3>My Agent</h3>
|
<h3>My Agent</h3>
|
||||||
<span class="agency-tag">🏢 Agency</span>
|
<span class="agency-tag">🏢 Agency</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="agent-card">
|
<div class="agent-card">
|
||||||
<div class="agent-info">
|
<div class="agent-info">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
@ -31,6 +31,7 @@
|
|||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ const userInfo = reactive({
|
|||||||
// 方法
|
// 方法
|
||||||
const leaveAgent = () => {
|
const leaveAgent = () => {
|
||||||
if (confirm('Are you sure you want to leave this agent?')) {
|
if (confirm('Are you sure you want to leave this agent?')) {
|
||||||
alert('Leave agent request submitted')
|
showError('Leave agent request submitted')
|
||||||
// 这里可以添加实际的离开代理商逻辑
|
// 这里可以添加实际的离开代理商逻辑
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,56 +28,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const teamId = ref('123456789')
|
|
||||||
|
|
||||||
// 复制团队ID
|
|
||||||
const copyTeamId = async () => {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(teamId.value)
|
|
||||||
alert('Team ID copied to clipboard!')
|
|
||||||
} catch (error) {
|
|
||||||
// 备选方案
|
|
||||||
const textArea = document.createElement('textarea')
|
|
||||||
textArea.value = teamId.value
|
|
||||||
document.body.appendChild(textArea)
|
|
||||||
textArea.select()
|
|
||||||
document.execCommand('copy')
|
|
||||||
document.body.removeChild(textArea)
|
|
||||||
alert('Team ID copied to clipboard!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享到微信
|
|
||||||
const shareToWeChat = () => {
|
|
||||||
alert('Share to WeChat functionality')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享链接
|
|
||||||
const shareLink = () => {
|
|
||||||
const shareText = `Join my team! Team ID: ${teamId.value}\nDownload Likei APP: https://likei.app`
|
|
||||||
|
|
||||||
if (navigator.share) {
|
|
||||||
navigator.share({
|
|
||||||
title: 'Join my team on Likei',
|
|
||||||
text: shareText,
|
|
||||||
url: 'https://likei.app'
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 备选方案
|
|
||||||
copyTeamId()
|
|
||||||
alert('Link copied! Share with your friends.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享二维码
|
|
||||||
const shareQRCode = () => {
|
|
||||||
alert('QR Code sharing functionality')
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@ -54,6 +54,7 @@ import MobileHeader from '../components/MobileHeader.vue'
|
|||||||
import { getApplyRecord } from '../api/teamBill.js'
|
import { getApplyRecord } from '../api/teamBill.js'
|
||||||
import { processUserApply } from '../api/wallet.js'
|
import { processUserApply } from '../api/wallet.js'
|
||||||
import {getTeamId} from "@/utils/userStore.js";
|
import {getTeamId} from "@/utils/userStore.js";
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -110,18 +111,18 @@ const handleAgree = async (message) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
alert(`已同意 ${message.name} 的申请`)
|
showError(`已同意 ${message.name} 的申请`)
|
||||||
// 从列表中移除
|
// 从列表中移除
|
||||||
const index = messages.value.findIndex(m => m.id === message.id)
|
const index = messages.value.findIndex(m => m.id === message.id)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
messages.value.splice(index, 1)
|
messages.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert('操作失败,请重试')
|
showError('操作失败,请重试')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('同意申请失败:', error)
|
console.error('同意申请失败:', error)
|
||||||
alert('操作失败,请重试')
|
showError('操作失败,请重试')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,18 +135,18 @@ const handleRefuse = async (message) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
alert(`已拒绝 ${message.name} 的申请`)
|
showError(`已拒绝 ${message.name} 的申请`)
|
||||||
// 从列表中移除
|
// 从列表中移除
|
||||||
const index = messages.value.findIndex(m => m.id === message.id)
|
const index = messages.value.findIndex(m => m.id === message.id)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
messages.value.splice(index, 1)
|
messages.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert('操作失败,请重试')
|
showError('操作失败,请重试')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('拒绝申请失败:', error)
|
console.error('拒绝申请失败:', error)
|
||||||
alert('操作失败,请重试')
|
showError('操作失败,请重试')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -105,6 +105,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { userBankCheckTransfer, userBankSearchUserProfile } from '../api/wallet.js'
|
import { userBankCheckTransfer, userBankSearchUserProfile } from '../api/wallet.js'
|
||||||
import { setSelectedPayee } from '../utils/payeeStore.js'
|
import { setSelectedPayee } from '../utils/payeeStore.js'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -252,7 +253,7 @@ const performSearch = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedUserType.value) {
|
if (!selectedUserType.value) {
|
||||||
alert('Please select user type first')
|
showError('Please select user type first')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +287,7 @@ const performSearch = async () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Search failed:', error)
|
console.error('Search failed:', error)
|
||||||
searchResults.value = []
|
searchResults.value = []
|
||||||
alert('User not found or search failed')
|
showError('User not found or search failed')
|
||||||
} finally {
|
} finally {
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,6 +77,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { getTeamMembers, deleteMember as deleteMemberApi } from '../api/teamBill.js'
|
import { getTeamMembers, deleteMember as deleteMemberApi } from '../api/teamBill.js'
|
||||||
import {getTeamId} from "@/utils/userStore.js";
|
import {getTeamId} from "@/utils/userStore.js";
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -157,7 +158,7 @@ const confirmDelete = async () => {
|
|||||||
closeDeleteModal()
|
closeDeleteModal()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to delete member:', error)
|
console.error('Failed to delete member:', error)
|
||||||
alert('Failed to delete member. Please try again.')
|
showError('Failed to delete member. Please try again.')
|
||||||
} finally {
|
} finally {
|
||||||
deletingMemberId.value = null
|
deletingMemberId.value = null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import {getBankBalance, userBankTransfer} from '../api/wallet.js'
|
import {getBankBalance, userBankTransfer} from '../api/wallet.js'
|
||||||
import { getSelectedPayee, clearSelectedPayee } from '../utils/payeeStore.js'
|
import { getSelectedPayee, clearSelectedPayee } from '../utils/payeeStore.js'
|
||||||
|
import {showError} from "@/utils/toast.js";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ const fetchBankBalance = async () => {
|
|||||||
console.error('Failed to fetch bank balance:', error)
|
console.error('Failed to fetch bank balance:', error)
|
||||||
availableSalary.value = '0.00'
|
availableSalary.value = '0.00'
|
||||||
// 可以显示错误提示
|
// 可以显示错误提示
|
||||||
alert('Failed to load balance. Please try again.')
|
showError('Failed to load balance. Please try again.')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -178,12 +179,12 @@ const selectCoin = (coin) => {
|
|||||||
|
|
||||||
const transfer = async () => {
|
const transfer = async () => {
|
||||||
if (!selectedCoin.value) {
|
if (!selectedCoin.value) {
|
||||||
alert('Please select an amount first')
|
showError('Please select an amount first')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedPayee.id) {
|
if (!selectedPayee.id) {
|
||||||
alert('Please select a payee first')
|
showError('Please select a payee first')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +193,7 @@ const transfer = async () => {
|
|||||||
// 获取支付密码
|
// 获取支付密码
|
||||||
// const password = prompt('Please enter your payment password:')
|
// const password = prompt('Please enter your payment password:')
|
||||||
// if (!password) {
|
// if (!password) {
|
||||||
// alert('Payment password is required')
|
// showError('Payment password is required')
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -209,7 +210,7 @@ const transfer = async () => {
|
|||||||
const response = await userBankTransfer(transferData)
|
const response = await userBankTransfer(transferData)
|
||||||
|
|
||||||
// 转账成功
|
// 转账成功
|
||||||
alert(`Successfully transferred $${selectedCoinData.price} to ${selectedPayee.name}`)
|
showError(`Successfully transferred $${selectedCoinData.price} to ${selectedPayee.name}`)
|
||||||
|
|
||||||
// 重置选择
|
// 重置选择
|
||||||
selectedCoin.value = null
|
selectedCoin.value = null
|
||||||
@ -222,11 +223,11 @@ const transfer = async () => {
|
|||||||
console.error('Transfer failed:', error)
|
console.error('Transfer failed:', error)
|
||||||
|
|
||||||
if (error.errorCode === 5000) {
|
if (error.errorCode === 5000) {
|
||||||
alert('Insufficient balance')
|
showError('Insufficient balance')
|
||||||
} else if (error.errorCode === 5010 || error.errorCode === 5009) {
|
} else if (error.errorCode === 5010 || error.errorCode === 5009) {
|
||||||
alert('Payment password error')
|
showError('Payment password error')
|
||||||
} else {
|
} else {
|
||||||
alert('Transfer failed, please try again later')
|
showError('Transfer failed, please try again later')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user