提示文案处理
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_USER_AUTH=03FF1925725628BD5319BAF8CAC4B1C8.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4MTgwNjE1ODAxJTNBMTc1NTU4ODYxNTgwMQ==
|
||||
VITE_USER_AUTH=657DB83B46ED88A0384D8FA9D83C1BA7.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4Mjc1MTUwMzQ2JTNBMTc1NTY4MzE1MDM0Ng==
|
||||
|
||||
# 代理用户 8826603
|
||||
# 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 {getBankBalance} from "@/api/wallet.js";
|
||||
import {getTeamId} from "@/utils/userStore.js";
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -266,7 +267,7 @@ const fetchBankBalance = async () => {
|
||||
console.error('Failed to fetch bank balance:', error)
|
||||
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">
|
||||
Pending
|
||||
</span>
|
||||
<button
|
||||
<button
|
||||
class="cancel-btn"
|
||||
@click="handleCancelApply(record)"
|
||||
>
|
||||
@ -96,6 +96,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { sendTeamApplyJoin, getWaitApplyRecord, cancelApply } from '../api/wallet.js'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -124,20 +125,20 @@ const handleCancelApply = async (record) => {
|
||||
if (!confirm('确定要撤销这个申请吗?')) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const response = await cancelApply(record.messageId)
|
||||
if (response.status) {
|
||||
alert('撤销成功!')
|
||||
showError('撤销成功!')
|
||||
// 刷新申请记录
|
||||
applyRecords.value = [] // 清空记录
|
||||
await fetchApplyRecords()
|
||||
} else {
|
||||
alert(response.message || '撤销失败,请重试')
|
||||
showError(response.message || '撤销失败,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('撤销申请失败:', error)
|
||||
alert('撤销失败,请重试')
|
||||
showError('撤销失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ const submitApplication = async () => {
|
||||
const response = await sendTeamApplyJoin(applicationData)
|
||||
|
||||
if (response.status) {
|
||||
alert('Application submitted successfully!')
|
||||
showError('Application submitted successfully!')
|
||||
await fetchApplyRecords() // 刷新申请记录
|
||||
agentId.value = '' // 清空输入
|
||||
} else {
|
||||
|
||||
@ -98,6 +98,7 @@ import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getSelectedUser, clearSelectedUser } from '../utils/coinSellerStore.js'
|
||||
import { checkFreightDealer, getTeamEntry, getFreightBalance, searchFreightUser, freightRecharge } from '../api/wallet.js'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -135,7 +136,7 @@ const checkDealerAccess = async () => {
|
||||
|
||||
if (!dealerAccess.value) {
|
||||
// 没有权限,跳转回上一页或首页
|
||||
alert('您没有金币销售商权限')
|
||||
showError('您没有金币销售商权限')
|
||||
router.go(-1)
|
||||
return
|
||||
}
|
||||
@ -223,14 +224,14 @@ const rechargeNow = async () => {
|
||||
|
||||
const amount = parseFloat(rechargeAmount.value)
|
||||
if (amount <= 0) {
|
||||
alert('请输入正确的充值金额')
|
||||
showError('请输入正确的充值金额')
|
||||
return
|
||||
}
|
||||
|
||||
// 需要获取接收用户的ID(从用户搜索结果中获取)
|
||||
const acceptUserId = selectedUser.value.userId || selectedUser.value.id
|
||||
if (!acceptUserId) {
|
||||
alert('无法获取用户ID,请重新选择用户')
|
||||
showError('无法获取用户ID,请重新选择用户')
|
||||
return
|
||||
}
|
||||
|
||||
@ -250,16 +251,16 @@ const rechargeNow = async () => {
|
||||
coinsAmount.value = response.body.toString()
|
||||
}
|
||||
|
||||
alert(`成功向 ${selectedUser.value.name} 充值 ${amount} 金币`)
|
||||
showError(`成功向 ${selectedUser.value.name} 充值 ${amount} 金币`)
|
||||
|
||||
// 重置表单
|
||||
rechargeAmount.value = ''
|
||||
} else {
|
||||
alert('充值失败,请重试')
|
||||
showError('充值失败,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('充值失败:', error)
|
||||
alert('充值失败,请检查网络后重试')
|
||||
showError('充值失败,请检查网络后重试')
|
||||
} finally {
|
||||
isRecharging.value = false
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getBankBalance, userSalaryCheckExchange, userBankExchangeGold } from '../api/wallet.js'
|
||||
import { showError } from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -90,7 +91,7 @@ const fetchBankBalance = async () => {
|
||||
console.error('Failed to fetch bank balance:', error)
|
||||
availableSalary.value = '0.00'
|
||||
// 可以显示错误提示
|
||||
alert('Failed to load balance. Please try again.')
|
||||
showError('Failed to load balance. Please try again.')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@ -125,13 +126,13 @@ const checkUserRole = async () => {
|
||||
// 处理特定错误情况
|
||||
if (error.errorCode === 1083) {
|
||||
// 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')) {
|
||||
// 处理 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 {
|
||||
// 其他错误情况
|
||||
alert('Failed to load user information')
|
||||
showError('Failed to load user information')
|
||||
}
|
||||
router.back() // 对于其他严重错误,也建议退出页面
|
||||
|
||||
@ -145,7 +146,7 @@ const checkUserRole = async () => {
|
||||
|
||||
const exchangeCoins = async () => {
|
||||
if (!selectedCoin.value) {
|
||||
alert('Please select a coin amount first')
|
||||
showError('Please select a coin amount first')
|
||||
return
|
||||
}
|
||||
|
||||
@ -156,7 +157,7 @@ const exchangeCoins = async () => {
|
||||
const availableBalance = parseFloat(availableSalary.value)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -173,7 +174,7 @@ const exchangeCoins = async () => {
|
||||
})
|
||||
|
||||
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()
|
||||
@ -184,11 +185,11 @@ const exchangeCoins = async () => {
|
||||
} else {
|
||||
// 接口调用失败
|
||||
const errorMessage = response.message || 'Exchange failed, please try again later.'
|
||||
alert(errorMessage)
|
||||
showError(errorMessage)
|
||||
}
|
||||
} catch (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 { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp } from '../utils/appBridge.js'
|
||||
import {getUserId, setUserInfo} from '../utils/userStore.js'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -223,7 +224,7 @@ const fetchBankBalance = async () => {
|
||||
console.error('Failed to fetch bank balance:', error)
|
||||
salaryInfo.currentSalary = 0.00
|
||||
// 可以显示错误提示
|
||||
alert('Failed to load balance. Please try again.')
|
||||
showError('Failed to load balance. Please try again.')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<h3>My Agent</h3>
|
||||
<span class="agency-tag">🏢 Agency</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="agent-card">
|
||||
<div class="agent-info">
|
||||
<div class="avatar">
|
||||
@ -31,6 +31,7 @@
|
||||
import { reactive } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -43,7 +44,7 @@ const userInfo = reactive({
|
||||
// 方法
|
||||
const leaveAgent = () => {
|
||||
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>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
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>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -54,6 +54,7 @@ import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getApplyRecord } from '../api/teamBill.js'
|
||||
import { processUserApply } from '../api/wallet.js'
|
||||
import {getTeamId} from "@/utils/userStore.js";
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
@ -110,18 +111,18 @@ const handleAgree = async (message) => {
|
||||
})
|
||||
|
||||
if (response.status) {
|
||||
alert(`已同意 ${message.name} 的申请`)
|
||||
showError(`已同意 ${message.name} 的申请`)
|
||||
// 从列表中移除
|
||||
const index = messages.value.findIndex(m => m.id === message.id)
|
||||
if (index > -1) {
|
||||
messages.value.splice(index, 1)
|
||||
}
|
||||
} else {
|
||||
alert('操作失败,请重试')
|
||||
showError('操作失败,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('同意申请失败:', error)
|
||||
alert('操作失败,请重试')
|
||||
showError('操作失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,18 +135,18 @@ const handleRefuse = async (message) => {
|
||||
})
|
||||
|
||||
if (response.status) {
|
||||
alert(`已拒绝 ${message.name} 的申请`)
|
||||
showError(`已拒绝 ${message.name} 的申请`)
|
||||
// 从列表中移除
|
||||
const index = messages.value.findIndex(m => m.id === message.id)
|
||||
if (index > -1) {
|
||||
messages.value.splice(index, 1)
|
||||
}
|
||||
} else {
|
||||
alert('操作失败,请重试')
|
||||
showError('操作失败,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('拒绝申请失败:', error)
|
||||
alert('操作失败,请重试')
|
||||
showError('操作失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -105,6 +105,7 @@ import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { userBankCheckTransfer, userBankSearchUserProfile } from '../api/wallet.js'
|
||||
import { setSelectedPayee } from '../utils/payeeStore.js'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -252,7 +253,7 @@ const performSearch = async () => {
|
||||
}
|
||||
|
||||
if (!selectedUserType.value) {
|
||||
alert('Please select user type first')
|
||||
showError('Please select user type first')
|
||||
return
|
||||
}
|
||||
|
||||
@ -286,7 +287,7 @@ const performSearch = async () => {
|
||||
} catch (error) {
|
||||
console.error('Search failed:', error)
|
||||
searchResults.value = []
|
||||
alert('User not found or search failed')
|
||||
showError('User not found or search failed')
|
||||
} finally {
|
||||
isSearching.value = false
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getTeamMembers, deleteMember as deleteMemberApi } from '../api/teamBill.js'
|
||||
import {getTeamId} from "@/utils/userStore.js";
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
@ -157,7 +158,7 @@ const confirmDelete = async () => {
|
||||
closeDeleteModal()
|
||||
} catch (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 {
|
||||
deletingMemberId.value = null
|
||||
}
|
||||
|
||||
@ -83,6 +83,7 @@ import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import {getBankBalance, userBankTransfer} from '../api/wallet.js'
|
||||
import { getSelectedPayee, clearSelectedPayee } from '../utils/payeeStore.js'
|
||||
import {showError} from "@/utils/toast.js";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -137,7 +138,7 @@ const fetchBankBalance = async () => {
|
||||
console.error('Failed to fetch bank balance:', error)
|
||||
availableSalary.value = '0.00'
|
||||
// 可以显示错误提示
|
||||
alert('Failed to load balance. Please try again.')
|
||||
showError('Failed to load balance. Please try again.')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@ -178,12 +179,12 @@ const selectCoin = (coin) => {
|
||||
|
||||
const transfer = async () => {
|
||||
if (!selectedCoin.value) {
|
||||
alert('Please select an amount first')
|
||||
showError('Please select an amount first')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedPayee.id) {
|
||||
alert('Please select a payee first')
|
||||
showError('Please select a payee first')
|
||||
return
|
||||
}
|
||||
|
||||
@ -192,7 +193,7 @@ const transfer = async () => {
|
||||
// 获取支付密码
|
||||
// const password = prompt('Please enter your payment password:')
|
||||
// if (!password) {
|
||||
// alert('Payment password is required')
|
||||
// showError('Payment password is required')
|
||||
// return
|
||||
// }
|
||||
|
||||
@ -209,7 +210,7 @@ const transfer = async () => {
|
||||
const response = await userBankTransfer(transferData)
|
||||
|
||||
// 转账成功
|
||||
alert(`Successfully transferred $${selectedCoinData.price} to ${selectedPayee.name}`)
|
||||
showError(`Successfully transferred $${selectedCoinData.price} to ${selectedPayee.name}`)
|
||||
|
||||
// 重置选择
|
||||
selectedCoin.value = null
|
||||
@ -222,11 +223,11 @@ const transfer = async () => {
|
||||
console.error('Transfer failed:', error)
|
||||
|
||||
if (error.errorCode === 5000) {
|
||||
alert('Insufficient balance')
|
||||
showError('Insufficient balance')
|
||||
} else if (error.errorCode === 5010 || error.errorCode === 5009) {
|
||||
alert('Payment password error')
|
||||
showError('Payment password error')
|
||||
} else {
|
||||
alert('Transfer failed, please try again later')
|
||||
showError('Transfer failed, please try again later')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user